可参考:http://blog.youkuaiyun.com/tonny_guan/article/details/9211797
很多app需要在访问手机中的通讯录,参考了一些文章,希望给大家带来帮助。
1.引入两个通讯录相关框架
#import
<AddressBookUI/AddressBookUI.h>
#import <AddressBook/AddressBook.h>
2.可以进入通讯录操作,要实现
ABPeoplePickerNavigationControllerDelegate协议
实现协议中的各种方法.
进入通讯录
ABPeoplePickerNavigationController
*picker = [
ABPeoplePickerNavigationController
new
];
picker. peoplePickerDelegate = self ;
picker. peoplePickerDelegate = self ;
[self presentViewController:picker animated:YES completion:nil];
协议中的各个方法:(如何添加删除联系人?)
//方法一
- (
void
)peoplePickerNavigationControllerDidCancel:(
ABPeoplePickerNavigationController
*)peoplePicker
{
[ self dismissViewControllerAnimated : YES completion : nil ];
{
[ self dismissViewControllerAnimated : YES completion : nil ];
}
//方法二
- (
void
)peoplePickerNavigationController:(
ABPeoplePickerNavigationController
*)peoplePicker didSelectPerson:(
ABRecordRef
)person
{
NSLog ( @" 选中联系人 " );
{
NSLog ( @" 选中联系人 " );
}
//方法三
- (
void
)peoplePickerNavigationController:(
ABPeoplePickerNavigationController
*)peoplePicker didSelectPerson:(
ABRecordRef
)person property:(
ABPropertyID
)property identifier:(
ABMultiValueIdentifier
)identifier
{
NSLog ( @" 选中联系人并调用该方法 " );
{
NSLog ( @" 选中联系人并调用该方法 " );
}
//方法四
-
BOOL
)peoplePickerNavigationController:(
ABPeoplePickerNavigationController
*)peoplePicker shouldContinueAfterSelectingPerson:(
ABRecordRef
)person
{
NSLog ( @" 选择联系人时将调用该方法 " );
// 获取联系人信息 : 似乎只能访问一部分联系人 , 而且该方法获取到当前选择的联系人
NSString *firstName = ( __bridge NSString *) ABRecordCopyValue (person, kABPersonFirstNameProperty );
NSLog ( @"---- 第一个联系人为 :%@" ,firstName);
return YES ;
NSLog ( @" 选择联系人时将调用该方法 " );
// 获取联系人信息 : 似乎只能访问一部分联系人 , 而且该方法获取到当前选择的联系人
NSString *firstName = ( __bridge NSString *) ABRecordCopyValue (person, kABPersonFirstNameProperty );
NSLog ( @"---- 第一个联系人为 :%@" ,firstName);
return YES ;
}
//方法五
- (
BOOL
)peoplePickerNavigationController:(
ABPeoplePickerNavigationController
*)peoplePicker shouldContinueAfterSelectingPerson:(
ABRecordRef
)person property:(
ABPropertyID
)property identifier:(
ABMultiValueIdentifier
)identifier
{
// 如果前一个方法为 NO 则不会调用该方法 , 若为 yes 表明允许用户进一步挖掘属性
NSLog ( @" 进一步挖掘用户的属性 " );
NSLog ( @"----person:%@" ,person);
NSLog ( @"----property:%d" ,property);
NSLog ( @"----identifier:%d" ,identifier);
return YES ;
{
// 如果前一个方法为 NO 则不会调用该方法 , 若为 yes 表明允许用户进一步挖掘属性
NSLog ( @" 进一步挖掘用户的属性 " );
NSLog ( @"----person:%@" ,person);
NSLog ( @"----property:%d" ,property);
NSLog ( @"----identifier:%d" ,identifier);
return YES ;
}
主要调用的方法有方法一,方法四
3.也可以不进入通讯录操作,实现通讯录的查询
CFErrorRef
error =
NULL
;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions ( NULL , &error);
ABAddressBookRequestAccessWithCompletion (addressBook, ^( bool granted, CFErrorRef error){
NSArray *linkArray = CFBridgingRelease ( ABAddressBookCopyArrayOfAllPeople (addressBook));
NSLog ( @"-----%@" ,linkArray);
// 显示联系人信息
for ( NSInteger i = 0 ; i < linkArray. count ; i ++)
{
ABRecordRef thisPerson = CFBridgingRetain ([linkArray objectAtIndex :i]);
NSString *firstName = CFBridgingRelease ( ABRecordCopyValue (thisPerson, kABPersonFirstNameProperty ));
firstName =firstName!= nil ? firstName : @"" ;
NSLog ( @" 第 %d 个联系人 firtName:%@" ,i,firstName);
NSString *lastName = CFBridgingRelease ( ABRecordCopyValue (thisPerson, kABPersonLastNameProperty ));
lastName = lastName!= nil ? lastName : @"" ;
NSLog ( @"lastName:%@" ,lastName);
ABRecordID personID = ABRecordGetRecordID (thisPerson);
NSLog ( @"Person:%d" ,personID); // 不是手机号,而是联系人的序列号
// 访问多值属性:如电话号码,邮件等可能有多个
ABMutableMultiValueRef phoneNumberProperty = ABRecordCopyValue (thisPerson, kABPersonPhoneProperty );
NSArray *phoneNumberArray = CFBridgingRelease ( ABMultiValueCopyArrayOfAllValues (phoneNumberProperty));
for ( NSString *phoneNUmber in phoneNumberArray)
{
NSLog ( @"phoneNumber:%@" ,phoneNUmber);
}
CFRelease (phoneNumberProperty);
CFRelease (thisPerson);
}
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions ( NULL , &error);
ABAddressBookRequestAccessWithCompletion (addressBook, ^( bool granted, CFErrorRef error){
NSArray *linkArray = CFBridgingRelease ( ABAddressBookCopyArrayOfAllPeople (addressBook));
NSLog ( @"-----%@" ,linkArray);
// 显示联系人信息
for ( NSInteger i = 0 ; i < linkArray. count ; i ++)
{
ABRecordRef thisPerson = CFBridgingRetain ([linkArray objectAtIndex :i]);
NSString *firstName = CFBridgingRelease ( ABRecordCopyValue (thisPerson, kABPersonFirstNameProperty ));
firstName =firstName!= nil ? firstName : @"" ;
NSLog ( @" 第 %d 个联系人 firtName:%@" ,i,firstName);
NSString *lastName = CFBridgingRelease ( ABRecordCopyValue (thisPerson, kABPersonLastNameProperty ));
lastName = lastName!= nil ? lastName : @"" ;
NSLog ( @"lastName:%@" ,lastName);
ABRecordID personID = ABRecordGetRecordID (thisPerson);
NSLog ( @"Person:%d" ,personID); // 不是手机号,而是联系人的序列号
// 访问多值属性:如电话号码,邮件等可能有多个
ABMutableMultiValueRef phoneNumberProperty = ABRecordCopyValue (thisPerson, kABPersonPhoneProperty );
NSArray *phoneNumberArray = CFBridgingRelease ( ABMultiValueCopyArrayOfAllValues (phoneNumberProperty));
for ( NSString *phoneNUmber in phoneNumberArray)
{
NSLog ( @"phoneNumber:%@" ,phoneNUmber);
}
CFRelease (phoneNumberProperty);
CFRelease (thisPerson);
}
});
4.添加联系人
//
初始化一个
ABAddressBookRef
对象,使用完之后需要进行释放,
// 这里使用 CFRelease 进行释放
// 相当于通讯录的一个引用
CFErrorRef error = NULL ;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions ( NULL , &error);
/* 新建一个联系人
*ABRecordRef 是一个属性的集合,相当于通讯录中联系人的对象
* 联系人对象的属性分两种:唯一值属性和多值属性
* 唯一值的属性包括:姓氏,名字,生日等
* 多值的属性包括:电话号码,邮箱等
*
*
*/
ABRecordRef person = ABPersonCreate (); // 相当于初始化
NSString *firstName = @" 三 " ;
NSString *lastName = @" 张 " ;
NSDate *birthday = [ NSDate date ];
// 电话号码数组
NSArray *phoneNumbers = @[ @"123" , @"3824655" ] ;
// 电话号码对应的名称 ( 即标签 )
NSArray *labels = @[ @"iphone" , @"home" ] ;
// 保存到联系人对象中,每一个属性对应一个宏,比如 kABPersonFirstNameProperty
// 设置 firstName 属性
ABRecordSetValue (person, kABPersonFirstNameProperty , ( __bridge CFStringRef )firstName, NULL );
// 设置 lastName 属性
ABRecordSetValue (person, kABPersonLastNameProperty , ( __bridge CFStringRef )lastName, NULL );
// 设置 birthDay 属性 : 当天出生
ABRecordSetValue (person, kABPersonBirthdayProperty , ( __bridge CFStringRef )birthday, NULL );
//ABMultiValueRef 类似是 Objective-C 中的 NSMutableDictionary
ABMultiValueRef mv = ABMultiValueCreateMutable ( kABMultiStringPropertyType );
// 添加电话号码与其对应的内容
for ( int i = 0 ;i < phoneNumbers. count ; i ++)
{
ABMultiValueIdentifier mi = ABMultiValueAddValueAndLabel (mv, ( __bridge CFStringRef )[phoneNumbers objectAtIndex :i], ( __bridge CFStringRef )[labels objectAtIndex :i], &mi);
}
// 设置 phone 属性
ABRecordSetValue (person, kABPersonPhoneProperty , mv, NULL );
// 释放该数组
if (mv)
{
CFRelease (mv);
}
// 将新建的联系人添加到通讯录中
ABAddressBookAddRecord (addressBook, person, NULL );
// 保存通讯录数据
ABAddressBookSave (addressBook, NULL );
// 释放通讯录对象的引用
if (addressBook)
{
CFRelease (addressBook);
// 这里使用 CFRelease 进行释放
// 相当于通讯录的一个引用
CFErrorRef error = NULL ;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions ( NULL , &error);
/* 新建一个联系人
*ABRecordRef 是一个属性的集合,相当于通讯录中联系人的对象
* 联系人对象的属性分两种:唯一值属性和多值属性
* 唯一值的属性包括:姓氏,名字,生日等
* 多值的属性包括:电话号码,邮箱等
*
*
*/
ABRecordRef person = ABPersonCreate (); // 相当于初始化
NSString *firstName = @" 三 " ;
NSString *lastName = @" 张 " ;
NSDate *birthday = [ NSDate date ];
// 电话号码数组
NSArray *phoneNumbers = @[ @"123" , @"3824655" ] ;
// 电话号码对应的名称 ( 即标签 )
NSArray *labels = @[ @"iphone" , @"home" ] ;
// 保存到联系人对象中,每一个属性对应一个宏,比如 kABPersonFirstNameProperty
// 设置 firstName 属性
ABRecordSetValue (person, kABPersonFirstNameProperty , ( __bridge CFStringRef )firstName, NULL );
// 设置 lastName 属性
ABRecordSetValue (person, kABPersonLastNameProperty , ( __bridge CFStringRef )lastName, NULL );
// 设置 birthDay 属性 : 当天出生
ABRecordSetValue (person, kABPersonBirthdayProperty , ( __bridge CFStringRef )birthday, NULL );
//ABMultiValueRef 类似是 Objective-C 中的 NSMutableDictionary
ABMultiValueRef mv = ABMultiValueCreateMutable ( kABMultiStringPropertyType );
// 添加电话号码与其对应的内容
for ( int i = 0 ;i < phoneNumbers. count ; i ++)
{
ABMultiValueIdentifier mi = ABMultiValueAddValueAndLabel (mv, ( __bridge CFStringRef )[phoneNumbers objectAtIndex :i], ( __bridge CFStringRef )[labels objectAtIndex :i], &mi);
}
// 设置 phone 属性
ABRecordSetValue (person, kABPersonPhoneProperty , mv, NULL );
// 释放该数组
if (mv)
{
CFRelease (mv);
}
// 将新建的联系人添加到通讯录中
ABAddressBookAddRecord (addressBook, person, NULL );
// 保存通讯录数据
ABAddressBookSave (addressBook, NULL );
// 释放通讯录对象的引用
if (addressBook)
{
CFRelease (addressBook);
}
5.删除联系人
// 初始化并创建通讯录对象,记得释放内存
ABAddressBookRef addressBook = ABAddressBookCreate();
// 获取通讯录中所有的联系人
NSArray *array = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
// 遍历所有的联系人并删除(这里只删除姓名为张三的)
for (id obj in array) {
ABRecordRef people = (ABRecordRef)obj;
NSString *firstName = (NSString *)ABRecordCopyValue(people, kABPersonFirstNameProperty);
NSString *lastName = (NSString *)ABRecordCopyValue(people, kABPersonLastNameProperty);
if ([firstName isEqualToString:@"三"] && [lastName isEqualToString:@"张"]) {
ABAddressBookRemoveRecord(addressBook, people, NULL);
}
}
// 保存修改的通讯录对象
ABAddressBookSave(addressBook, NULL);
// 释放通讯录对象的内存
if (addressBook) {
CFRelease(addressBook);
}
6.修改联系人
// 根据姓氏、名字以及手机号码修改联系人的昵称和生日
+ (void) updateAddressBookPersonWithFirstName:(NSString *)firstName
lastName:(NSString *)lastName
mobile:(NSString *)mobile
nickname:(NSString *)nickname
birthday:(NSDate *)birthday {
// 初始化并创建通讯录对象,记得释放内存
ABAddressBookRef addressBook = ABAddressBookCreate();
// 获取通讯录中所有的联系人
NSArray *array = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
// 遍历所有的联系人并修改指定的联系人
for (id obj in array) {
ABRecordRef people = (ABRecordRef)obj;
NSString *fn = (NSString *)ABRecordCopyValue(people, kABPersonFirstNameProperty);
NSString *ln = (NSString *)ABRecordCopyValue(people, kABPersonLastNameProperty);
ABMultiValueRef mv = ABRecordCopyValue(people, kABPersonPhoneProperty);
NSArray *phones = (NSArray *)ABMultiValueCopyArrayOfAllValues(mv);
// firstName同时为空或者firstName相等
BOOL ff = ([fn length] == 0 && [firstName length] == 0) || ([fn isEqualToString:firstName]);
// lastName同时为空或者lastName相等
BOOL lf = ([ln length] == 0 && [lastName length] == 0) || ([ln isEqualToString:lastName]);
// 由于获得到的电话号码不符合标准,所以要先将其格式化再比较是否存在
BOOL is = NO;
for (NSString *p in phones) {
// 红色代码处,我添加了一个类别(给NSString扩展了一个方法),该类别的这个方法主要是用于将电话号码中的"("、")"、" "、"-"过滤掉
if ([[p iPhoneStandardFormat] isEqualToString:mobile]) {
is = YES;
break;
}
}
// firstName、lastName、mobile 同时存在进行修改
if (ff && lf && is) {
if ([nickname length] > 0) {
ABRecordSetValue(people, kABPersonNicknameProperty, (CFStringRef)nickname, NULL);
}
if (birthday != nil) {
ABRecordSetValue(people, kABPersonBirthdayProperty, (CFDataRef)birthday, NULL);
}
}
}
// 保存修改的通讯录对象
ABAddressBookSave(addressBook, NULL);
// 释放通讯录对象的内存
if (addressBook) {
CFRelease(addressBook);
}
}