先来分析一下,二维码扫描后,可能得到什么东西:网址,EMAIL,电话,名片等这几种应该是比较常用的。
先贴几张图
1.扫描按钮
2.zxing二维码扫描界面(这个界面可以自己画)
3.扫描到网页界面
4.扫描名片后的界面
二维码是这个:
扫描后:
5.保存到联系人,调用系统联系人界面
1.操作思想:
1.1 网址:主要两种是:"http://","https://"。所以我用的到方法就是判断字符串是否以"http://"或其他几种开头,这里需要注意
的是。[string1 hasPrefix: string2]; 这个方法是区分大小写的。所以注意,我们扫描出来的可能是"HTTP://"。
2.2 邮箱跟电话这里我没有去做判断,有需要的朋友可以自己判断一下。
3.3 名片:我做的这个项目主要是为了识别名片,所以这里多说一些。经过在网页上找到的二维码扫描结果发现,很多名片
格式是这样的:"BEGIN:VCARD"、"BEGIN CARD:“、 ”MECARD:“ 、"CARD:"这几种。因为我没有在网上找名片格式的解析,都
是自己来判断的。
2.代码:
需要引入
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
//正常扫描退出事件>
- (void)zxingController:(ZXingWidgetController*)controller didScanResult:(NSString *)result {
//resultsToDisplay :NSString类型
self.resultsToDisplay = result;
NSLog(@"result是: %@",result);
//第一种,判断如果是这个格式
if ([result hasPrefix:@"BEGIN:VCARD"]){
vCardArr = [[NSDictionary alloc] init];
NSString *a = [resolveVcard vcardTurnToMutableArray:result];
vCardArr = [[a JSONValue] retain];
NSLog(@"vCardArr是: %@",vCardArr);
if ([vCardArr count]> 0 ) {
btnOpen.hidden = YES;
finalArr = [[NSMutableArray alloc] init];
for (id key in vCardArr) {
if (![[NSString stringWithFormat:@"%@",[vCardArr objectForKey:key]] isEqualToString:@""]) {
NSString *Astr = [resolveVcard whatString:key:[vCardArr objectForKey:key]];
[finalArr addObject:Astr];
}
}
NSLog(@"退出后finalArr count==%d",[finalArr count]);
if ([finalArr count] >0) {
[resultsView setHidden:YES];
[tabCard reloadData];
tabCard.hidden = NO;
addBook.hidden = NO;
}
}
}else //另外的几种格式,都包含CARD:。所以这里判断一下,是否查找到CARD:
if ([result rangeOfString:@"CARD:"].location !=NSNotFound) {
// }
// if ([result hasPrefix:@"BEGIN CARD:"] || [result hasPrefix:@"MECARD:"] || [result hasPrefix:@"CARD:"]){
vCardArr = [[NSDictionary alloc] init];
NSString *a = [resolveVcard mecardTurnToMutableArray:result];
vCardArr = [[a JSONValue] retain];
if ([vCardArr count]> 0 ) {
btnOpen.hidden = YES;
finalArr = [[NSMutableArray alloc] init];
for (id key in vCardArr) {
if (![[NSString stringWithFormat:@"%@",[vCardArr objectForKey:key]] isEqualToString:@""]) {
NSString *Astr = [resolveVcard whatString:key:[vCardArr objectForKey:key]];
[finalArr addObject:Astr];
}
}
NSLog(@"退出后finalArr count==%d",[finalArr count]);
if ([finalArr count] >0) {
[resultsView setHidden:YES];
tabCard.hidden = NO;
[tabCard reloadData];
addBook.hidden = NO;
}
}
}else
if (self.isViewLoaded) {
[addBook setHidden:YES];
btnOpen.hidden = YES;
[tabCard setHidden:YES];
[resultsView setHidden:NO];
[resultsView setText:resultsToDisplay];
[resultsView setNeedsDisplay];
if ([resultsToDisplay hasPrefix:@"http://"] ||[resultsToDisplay hasPrefix:@"https://"] ||[resultsToDisplay hasPrefix:@"HTTP://"] ||[resultsToDisplay hasPrefix:@"HTTPS://"]) {
btnOpen.hidden = NO;
[btnOpen setTitle:@"打开网页" forState:UIControlStateNormal];
}
}
[self dismissModalViewControllerAnimated:NO];
}
[resolveVcard vcardTurnToMutableArray:result];//resolveVcard 是另一个文件需要引入。下面贴出代码
resolveVcard.h
#import <Foundation/Foundation.h>
@interface resolveVcard : NSObject
+ (NSString *) vcardTurnToMutableArray:(NSString *) cardString;
+ (NSString *) mecardTurnToMutableArray:(NSString *) cardString;
+ (NSString *) whatString:(id) cardString:(id)valueId;
@end
resolveVcard.m
#import "resolveVcard.h"
@implementation resolveVcard
+ (NSString *) whatString:(id) cardString:(id)valueId
{
NSLog(@"valueId===%@===",valueId);
NSString *valueStr = [NSString stringWithFormat:@"%@",valueId];
NSLog(@"id===%@===",cardString);
NSString *resultStr = [NSString stringWithFormat:@""];
if ([cardString isEqual:@"NAME"]) {
resultStr = [resultStr stringByAppendingFormat:@"姓名: "];
resultStr = [resultStr stringByAppendingFormat:valueStr];
}if ([cardString isEqual:@"TEL"]) {
resultStr = [resultStr stringByAppendingFormat:@"电话: "];
resultStr = [resultStr stringByAppendingFormat:valueStr];
}if ([cardString isEqual:@"EMAIL"]) {
resultStr = [resultStr stringByAppendingFormat:@"邮箱: "];
resultStr = [resultStr stringByAppendingFormat:valueStr];
}if ([cardString isEqual:@"ADDRESS"]) {
resultStr = [resultStr stringByAppendingFormat:@"地址: "];
resultStr = [resultStr stringByAppendingFormat:valueStr];
}if ([cardString isEqual:@"ORG"]) {
resultStr = [resultStr stringByAppendingFormat:@"公司: "];
resultStr = [resultStr stringByAppendingFormat:valueStr];
}if ([cardString isEqual:@"URL"]) {
resultStr = [resultStr stringByAppendingFormat:@"网址: "];
resultStr = [resultStr stringByAppendingFormat:valueStr];
}
NSLog(@"resultStr===%@===",resultStr);
return resultStr;
}
//其他格式
+ (NSString *) mecardTurnToMutableArray:(NSString *) cardString
{
/*
BEGIN CARD:N:李XX;COR:公司名;TIL:经理;TEL:13899;M:186000;EM:xx@xx.com;IM:QQ 1232;ADR:地址;URL:http://xxx.com;;
*/
/*
MECARD:N:aaaaa;TEL:234234;EMAIL:3434;ADR:rrrrrrrrrr;URL:http
*/
/*
CARD:N:李XX;COR:公司名;ADR:地址;ZIP:43000;TEL:0239999;M:186393939;EM:KK@KK.COM;URL:HTTP://BAIDU.COM;;
*/
NSArray *cardArray;
// 去除CARD:及之前的字符串
cardString = [cardString substringFromIndex:([cardString rangeOfString: @"CARD:"].location+@"CARD:".length)];
//没有找到更好的方法,所以还是使用死方法,定死数组字段名。如果以后找到更好的方法再更改
//预设定:NAME,TEL,EMAIL,ADDRESS,ORG,URL
cardArray = [cardString componentsSeparatedByString:@";"];
//a 是一种JSON格式。方便转目录或者数组
NSString *a = [NSString stringWithFormat:@"{"];
for (NSString *str in cardArray) {
NSLog(@"str in cardArray is==%@==",str);
//提取NAME名字
if ([str hasPrefix:@"N:"]) {
a = [a stringByAppendingString:@"\"NAME\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"N:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取TEL电话
if ([str hasPrefix:@"TEL:"]) {
a = [a stringByAppendingString:@"\"TEL\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"TEL:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取EMAIL电邮
if ([str hasPrefix:@"EMAIL:"]) {
a = [a stringByAppendingString:@"\"EMAIL\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"EMAIL:".length)]];
a = [a stringByAppendingString:@"\","];
}
if ([str hasPrefix:@"EM:"]) {
a = [a stringByAppendingString:@"\"EMAIL\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"EM:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取ADR地址
if ([str hasPrefix:@"ADR:"]) {
a = [a stringByAppendingString:@"\"ADDRESS\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"ADR:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取ORG公司
if ([str hasPrefix:@"ORG:"]) {
a = [a stringByAppendingString:@"\"ORG\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"ORG:".length)]];
a = [a stringByAppendingString:@"\","];
}
if ([str hasPrefix:@"COR:"]) {
a = [a stringByAppendingString:@"\"ORG\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"COR:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取URL网址
if ([str hasPrefix:@"URL:"]) {
a = [a stringByAppendingString:@"\"URL\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"URL:".length)]];
a = [a stringByAppendingString:@"\","];
}
}
a = [a stringByAppendingString:@"\"end数组结束end\":\""];
a = [a stringByAppendingString:@""];
a = [a stringByAppendingFormat:@"\"}"];
NSLog(@"a==%@",a);
return a;
}
//将标准vcard数据转可变数组
+ (NSString *) vcardTurnToMutableArray:(NSString *) cardString
{
/*
//以下是一个标准的vcard格式
BEGIN:VCARD
VERSION:3.0
N:X;XX
TEL:1383838438
EMAIL:xx@xx.com
ADR:;;地址;;城市;邮编
ORG:公司
TITLE:
URL:网址
NOTE:QQ:998
END:VCARD
*/
NSArray *cardArray;
//判断是否是正规的vcard格式
if ([cardString hasPrefix:@"BEGIN:VCARD"]){
//去除掉头部
cardString = [cardString substringFromIndex:(@"BEGIN:VCARD\n".length)];
NSLog(@"取后的cardstring :===%@==",cardString);
//分割转换成数组
cardArray = [cardString componentsSeparatedByString:@"\n"];
NSLog(@"分割后的数组 :%@",cardArray);
}
//没有找到更好的方法,所以还是使用死方法,定死数组字段名。如果以后找到更好的方法再更改
//预设定:NAME,TEL,EMAIL,ADDRESS,ORG,URL
NSString *a = [NSString stringWithFormat:@"{"];
for (NSString *str in cardArray) {
NSLog(@"str in cardArray is==%@==",str);
//提取NAME名字
if ([str hasPrefix:@"N:"]) {
a = [a stringByAppendingString:@"\"NAME\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"N:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取TEL电话
if ([str hasPrefix:@"TEL:"]) {
a = [a stringByAppendingString:@"\"TEL\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"TEL:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取EMAIL电邮
if ([str hasPrefix:@"EMAIL:"]) {
a = [a stringByAppendingString:@"\"EMAIL\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"EMAIL:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取EMAIL电邮
if ([str hasPrefix:@"ADR:"]) {
a = [a stringByAppendingString:@"\"ADDRESS\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"ADR:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取EMAIL电邮
if ([str hasPrefix:@"ORG:"]) {
a = [a stringByAppendingString:@"\"ORG\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"ORG:".length)]];
a = [a stringByAppendingString:@"\","];
}
//提取EMAIL电邮
if ([str hasPrefix:@"URL:"]) {
a = [a stringByAppendingString:@"\"URL\":\""];
a = [a stringByAppendingString:[str substringFromIndex:(@"URL:".length)]];
a = [a stringByAppendingString:@"\","];
}
}
a = [a stringByAppendingString:@"\"end数组结束end\":\""];
a = [a stringByAppendingString:@""];
a = [a stringByAppendingFormat:@"\"}"];
NSLog(@"a==%@",a);
return a;
}
@end
增加联系人的方法
//增加联系人按钮事件
- (IBAction)createOne:(id)sender
{
if ([finalArr count] > 0) {
ABNewPersonViewController *newPersonViewController = [[ABNewPersonViewController alloc] init];
//创建一条联系人记录
ABRecordRef tmpRecord = ABPersonCreate();
CFErrorRef error;
BOOL tmpSuccess = NO;
for (int i = 0; i < [finalArr count]; i++) {
NSString *firstStr = [[finalArr objectAtIndex:i] substringToIndex:(@"前部: ".length)];
NSString *SecondStr = [[finalArr objectAtIndex:i] substringFromIndex:(@"前部: ".length)];
NSLog(@"firstStr:==%@==SecondStr===%@==",firstStr,SecondStr);
if ([firstStr hasPrefix:@"姓名: "]) {
NSString *name = [NSString stringWithFormat: SecondStr];
NSString *Xname = [NSString stringWithFormat:@""];
//如果有分割 如:X;XX
if ([name rangeOfString:@";"].location !=NSNotFound) {
Xname = [name substringToIndex:([name rangeOfString:@";"].location)];
name = [name substringFromIndex:([name rangeOfString:@";"].location+1)];
}
//First name 名 --OK
//注意转换类型
CFStringRef tmpFirstName = CFStringRef(name);
tmpSuccess = ABRecordSetValue(tmpRecord, kABPersonFirstNameProperty, tmpFirstName, &error);
// CFRelease(tmpFirstName);
//Last name 姓 --OK
CFStringRef tmpLastName = CFStringRef(Xname);
tmpSuccess = ABRecordSetValue(tmpRecord, kABPersonLastNameProperty, tmpLastName, &error);
// CFRelease(tmpLastName);
}
if ([firstStr hasPrefix:@"电话: "]) {
CFStringRef tel = CFStringRef([NSString stringWithFormat:SecondStr]);
//phone number
//CFSTR("13902400000")
//注意转换类型
// NSString *tmpPhones = [NSString stringWithFormat:tel];
// CFStringRef tmpPhones = CFSTR("13902400000");
ABMutableMultiValueRef tmpMutableMultiPhones = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(tmpMutableMultiPhones, tel, kABPersonPhoneMobileLabel, NULL);
tmpSuccess = ABRecordSetValue(tmpRecord, kABPersonPhoneProperty, tmpMutableMultiPhones, &error);
// CFRelease(tmpPhones);
}
if ([firstStr hasPrefix:@"邮箱: "]) {
CFStringRef mail = CFStringRef([NSString stringWithFormat:SecondStr]);
//email 邮件
ABMutableMultiValueRef tmpMutableMultiEmails = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(tmpMutableMultiEmails, mail, kABWorkLabel, NULL);
tmpSuccess = ABRecordSetValue(tmpRecord, kABPersonEmailProperty, tmpMutableMultiEmails, &error);
// CFRelease(tmpEmail);
}
if ([firstStr hasPrefix:@"公司: "]) {
NSString *org = [NSString stringWithFormat:SecondStr];
//公司 --OK
CFStringRef tmpCompany = CFStringRef(org);
tmpSuccess = ABRecordSetValue(tmpRecord, kABPersonOrganizationProperty, tmpCompany, &error);
// CFRelease(tmpCompany);
}
if ([firstStr hasPrefix:@"网址: "]) {
CFStringRef url = CFStringRef([NSString stringWithFormat:SecondStr]);
//网址
ABMutableMultiValueRef tmpMutableMultiUrls = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(tmpMutableMultiUrls, url, kABWorkLabel, NULL);
tmpSuccess = ABRecordSetValue(tmpRecord, kABPersonURLProperty, tmpMutableMultiUrls, &error);
// CFRelease(tmpUrl);
}
if ([firstStr hasPrefix:@"地址: "]) {
NSString *address = [NSString stringWithFormat:SecondStr];
//地址
//;;xxx;;XX;400039
NSString *strCity = [NSString stringWithFormat:@""];
NSString *strState = [NSString stringWithFormat:@""];
NSString *strZip = [NSString stringWithFormat:@""];
NSString *strCountry = [NSString stringWithFormat:@""];
NSString *strCountryCode = [NSString stringWithFormat:@""];
if ([address rangeOfString:@";"].location != NSNotFound) {
NSArray *addarray = [address componentsSeparatedByString:@";"];
if ([addarray count] == 6) {
address = [NSString stringWithFormat:[addarray objectAtIndex:2]];
strCity = [NSString stringWithFormat:[addarray objectAtIndex:4]];
strState = [NSString stringWithFormat:[addarray objectAtIndex:3]];
strZip = [NSString stringWithFormat:[addarray objectAtIndex:5]];
strCountry = [NSString stringWithFormat:[addarray objectAtIndex:1]];
strCountryCode = [NSString stringWithFormat:[addarray objectAtIndex:0]];
}
}
ABMutableMultiValueRef multiAddress = ABMultiValueCreateMutable(kABDictionaryPropertyType);
NSMutableDictionary *addressDictionary = [[NSMutableDictionary alloc] init];
[addressDictionary setObject:address forKey:(NSString *) kABPersonAddressStreetKey];
[addressDictionary setObject:strCity forKey:(NSString *)kABPersonAddressCityKey];
[addressDictionary setObject:strState forKey:(NSString *)kABPersonAddressStateKey];
[addressDictionary setObject:strZip forKey:(NSString *)kABPersonAddressZIPKey];
[addressDictionary setObject:strCountry forKey:(NSString *)kABPersonAddressCountryKey];
[addressDictionary setObject:strCountryCode forKey:(NSString *)kABPersonAddressCountryCodeKey];
ABMultiValueIdentifier identifier;
ABMultiValueAddValueAndLabel(multiAddress, addressDictionary, kABWorkLabel, &identifier);
tmpSuccess =ABRecordSetValue(tmpRecord, kABPersonAddressProperty, multiAddress, &error);
CFRelease(multiAddress);
CFRelease(addressDictionary);
}
}
newPersonViewController.displayedPerson = tmpRecord;
newPersonViewController.newPersonViewDelegate = self;
[self.navigationController pushViewController:newPersonViewController animated:YES];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
}
//联系人界面CANCEL事件
- (void) newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person
{
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.navigationController popViewControllerAnimated:YES];
}
//上面的代码中,有些地方用了CFRelease。有些没有用。是因为测试发现有的地方用了就报错。
CFRelease()
代码比较混乱,如果中间有什么问题。大家可以加入 QQ群:28433020 交流