iOS手机通信录的实现
一,使用AddressBook.framework框架实现(框架基于C语言,需要自己释放内存)
添加头文件<AddressBook/AddressBook.h>
1.首先创建通讯录对象,通过该对象来调用AddressBook提供的标准API来实现通讯录操作
ABAddressBookRef addressBook=ABAddressBookCreateWithOptions(NULL, NULL);
2.请求访问用户通信录,无论成功与否都会调用block块函数
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if(!granted)
{
//未获得权限
}else{
//可以继续进行读取通信录数据操作,先判断访问授权
}
}
3.取得通讯录访问授权
ABAuthorizationStatus authorization= ABAddressBookGetAuthorizationStatus();
if(authorization!=kABAuthorizationStatusAuthorized)
{
//未获得通讯录访问授权,无法操作了
}else{
//可以继续操作,读取通信录用户
}
4.读取通信录用户操作
CFArrayRef allPeople= ABAddressBookCopyArrayOfAllPeople(addressBook);
NSMutableArray *arrAllPerson=(__bridge NSMutableArray *)allPeople;//用数组转换接收
CFRelease(allPeople); //必须记得释放资源
5.从arrAllPerson数组中获取通讯录中每个联系人的信息
ABRecordRef recordRef=(__bridge ABRecordRef)allPerson;
long userID =ABRecordGetRecordID(recordRef);//记录用户ID,以备后用
NSString *firstName=(__bridge NSString *) ABRecordCopyValue(recordRef, kABPersonFirstNameProperty);//注意这里进行了强转,不用自己释放资源 姓
NSString *lastName=(__bridge NSString *)ABRecordCopyValue(recordRef, kABPersonLastNameProperty);// 名称
ABMultiValueRef phoneNumbersRef= ABRecordCopyValue(recordRef, kABPersonPhoneProperty);//获取手机号,注意手机号是ABMultiValueRef类,有可能有多条
NSArray *phoneNumbers=(__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneNumbersRef);//取得CFArraryRef类型的手机记录并转化为NSArrary
long count= ABMultiValueGetCount(phoneNumbersRef);
for(long i=0;i<count;i++)
{
NSString * phoneNum=ABMultiValueCopyValueAtIndex(phoneNumbersRef, i)//取出每条数据
}
if(ABPersonHasImageData(recordRef)){//如果有照片数据,取出数据
NSData *imageData= (__bridge NSData *)(ABPersonCopyImageData(recordRef));
}
6.对联系人的操作,增删改
通过用户名,电话查找对应联系人记录,
CFStringRef personNameRef=(__bridge CFStringRef)(personName);
CFArrayRef recordsRef= ABAddressBookCopyPeopleWithName(addressBook, personNameRef);//根据人员姓名查找
CFIndex count= CFArrayGetCount(recordsRef);//取得记录数
for (CFIndex i=0; i<count; ++i) {
ABRecordRef recordRef=CFArrayGetValueAtIndex(recordsRef, i);//取得指定的记录
ABAddressBookRemoveRecord(addressBook, recordRef, NULL);//删除
ABAddressBookSave(addressBook, NULL);//删除之后提交更改
}
CFRelease(recordsRef);//释放资源
添加联系人
ABRecordRef recordRef= ABPersonCreate();//创建一条记录
ABRecordSetValue(recordRef, kABPersonFirstNameProperty, (__bridge CFTypeRef)(firstName), NULL);//添加名
ABRecordSetValue(recordRef, kABPersonLastNameProperty, (__bridge CFTypeRef)(lastName), NULL);//添加姓
ABMutableMultiValueRef multiValueRef =ABMultiValueCreateMutable(kABStringPropertyType);//添加设置多值属性
ABMultiValueAddValueAndLabel(multiValueRef, (__bridge CFStringRef)(workNumber), kABWorkLabel, NULL);//添加工作电话
ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);
ABAddressBookAddRecord(addressBook, recordRef, NULL);//添加记录
ABAddressBookSave(addressBook, NULL); //保存通讯录,提交更改
CFRelease(recordRef); //释放资源
CFRelease(multiValueRef);
更改联系人信息
ABRecordRef recordRef=ABAddressBookGetPersonWithRecordID(addressBook,recordID);
ABRecordSetValue(recordRef, kABPersonFirstNameProperty, (__bridge CFTypeRef)(firstName), NULL);//添加名
ABRecordSetValue(recordRef, kABPersonLastNameProperty, (__bridge CFTypeRef)(lastName), NULL);//添加姓
ABMutableMultiValueRef multiValueRef =ABMultiValueCreateMutable(kABStringPropertyType);
ABMultiValueAddValueAndLabel(multiValueRef, (__bridge CFStringRef)(workNumber), kABWorkLabel, NULL);
ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);
ABAddressBookSave(addressBook, NULL); //保存记录,提交更改
CFRelease(multiValueRef); //释放资源
二,AddressBook.framework可以对通讯录有更加精确的控制,但是缺点就是面对大量C语言API稍嫌麻烦苹果官方提供了AddressBookUI.framework框架来实现通讯录,其中的一些查看、新增、修改人员的界面这个框架就提供了现成的控制器视图供开发者使用
以下三个视图控制器均继承于UIViewController,在使用过程中必须使用一个UINavigationController进行包装,否则只能看到视图内容无法进行操作
ABPersonViewController:用于查看联系人信息(可设置编辑)。需要设置displayedPerson属性来设置要显示或编辑的联系人。
ABNewPersonViewController:用于新增联系人信息。
ABUnknownPersonViewController:用于显示一个未知联系人信息。需要设置displayedPerson属性来设置要显示的未知联系人。
添加头文件及需要遵循的代理协议
#import <AddressBookUI/AddressBookUI.h>
<ABNewPersonViewControllerDelegate,ABUnknownPersonViewControllerDelegate,ABPeoplePickerNavigationControllerDelegate,ABPersonViewControllerDelegate>
添加新联系人
ABNewPersonViewController *newPersonController=[[ABNewPersonViewController alloc]init];
newPersonController.newPersonViewDelegate=self;
UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:newPersonController];
[self presentViewController:navigationController animated:YES completion:nil];
显示未知人员信息
ABUnknownPersonViewController *unknownPersonController=[[ABUnknownPersonViewController alloc]init];
ABRecordRef recordRef=ABPersonCreate();
ABRecordSetValue(recordRef, kABPersonFirstNameProperty, @firstName”, NULL);
ABRecordSetValue(recordRef, kABPersonLastNameProperty, @“lastName”, NULL);
ABMultiValueRef multiValueRef=ABMultiValueCreateMutable(kABStringPropertyType);
ABMultiValueAddValueAndLabel(multiValueRef, @“18818818888”, kABHomeLabel, NULL);
ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);
unknownPersonController.displayedPerson=recordRef;
unknownPersonController.unknownPersonViewDelegate=self;//设置代理
unknownPersonController.allowsActions=YES;//显示标准操作按钮
unknownPersonController.allowsAddingToAddressBook=YES;//是否允许将联系人添加到地址簿
CFRelease(multiValueRef);
CFRelease(recordRef);
UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:unknownPersonController];
[self presentViewController:navigationController animated:YES completion:nil];
显示指定联系人
ABPersonViewController *personController=[[ABPersonViewController alloc]init];
ABAddressBookRef addressBook=ABAddressBookCreateWithOptions(NULL, NULL);
ABRecordRef recordRef= ABAddressBookGetPersonWithRecordID(addressBook, 1);//取得id为1的联系人记录
personController.displayedPerson=recordRef;
personController.personViewDelegate=self; //设置代理
personController.allowsActions=YES;//是否显示发送信息、共享联系人等按钮
personController.allowsEditing=YES;//允许编辑
personController.displayedProperties=@[@(kABPersonFirstNameProperty),@(kABPersonLastNameProperty)];//显示的联系人属性信息,默认显示所有信息
UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:personController];
[self presentViewController:navigationController animated:YES completion:nil];
显示所有联系人,按字母顺序排列,供用户选择
ABPeoplePickerNavigationController *peoplePickerController=[[ABPeoplePickerNavigationController alloc]init]
peoplePickerController.peoplePickerDelegate=self;
[self presentViewController:peoplePickerController animated:YES completion:nil];
ABNewPersonViewController代理方法
//完成新增(点击取消和完成按钮时调用),此处不用做实际增加工作,此代理方法调用时已经完成新增,当保存成功的时候person会返回保存的记录,如果点击取消person为NULL
-(void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person{
if (person) {
NSLog(@"%@ 信息保存成功.",(__bridge NSString *)(ABRecordCopyCompositeName(person)));
}else{
NSLog(@"点击了取消.");
}
}
ABUnknownPersonViewController代理方法
//保存未知联系人时触发
-(void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownCardViewController didResolveToPerson:(ABRecordRef)person{
if (person) {
NSLog(@"%@ 信息保存成功!",(__bridge NSString *)(ABRecordCopyCompositeName(person)));
}
}
//选择未知联系人的一个属性后触发,返回值YES表示触发默认行为操作,否则执行代理中自定义的操作
-(BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
if (person) {
NSLog(@"选择了属性:%i,值:%@.",property,(__bridge NSString *)ABRecordCopyValue(person, property));
}
return NO;
}
ABPersonViewController代理方法
//选择一个人员属性后触发,返回值YES表示触发默认行为操作,否则执行代理中自定义的操作
-(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
if (person) {
NSLog(@"选择了属性:%i,值:%@.",property,(__bridge NSString *)ABRecordCopyValue(person, property));
}
return NO;
}
ABPeoplePickerNavigationController代理方法
//选择一个联系人后,注意这个代理方法实现后属性选择的方法将不会再调用
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person{
if (person) {
NSLog(@"选择了%@.",(__bridge NSString *)(ABRecordCopyCompositeName(person)));
}
}
//选择属性之后,注意如果上面的代理方法实现后此方法不会被调用
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
if (person && property) {
NSLog(@"选择了属性:%i,值:%@.",property,(__bridge NSString *)ABRecordCopyValue(person, property));
}
}
//点击取消按钮
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{
}