可参考:http://blog.csdn.net/tonny_guan/article/details/9211797
很多app需要在访问手机中的通讯录,参考了一些文章,希望给大家带来帮助。
1.引入两个通讯录相关框架
#import
<AddressBookUI/AddressBookUI.h>
#import <AddressBook/AddressBook.h>
2.可以进入通讯录操作,要实现
ABPeoplePickerNavigationControllerDelegate协议
实现协议中的各种方法.
进入通讯录
ABPeoplePickerNavigationController
*picker = [
ABPeoplePickerNavigationController
new
];
picker.
peoplePickerDelegate
=
self
;
[self presentViewController:picker animated:YES completion:nil];
协议中的各个方法:(如何添加删除联系人?)
//方法一
- (
void
)peoplePickerNavigationControllerDidCancel:(
ABPeoplePickerNavigationController
*)peoplePicker
{
[
self
dismissViewControllerAnimated
:
YES
completion
:
nil
];
}
//方法二
- (
void
)peoplePickerNavigationController:(
ABPeoplePickerNavigationController
*)peoplePicker didSelectPerson:(
ABRecordRef
)person
{
NSLog
(
@"
选中联系人
"
);
}
//方法三
- (
void
)peoplePickerNavigationController:(
ABPeoplePickerNavigationController
*)peoplePicker didSelectPerson:(
ABRecordRef
)person property:(
ABPropertyID
)property identifier:(
ABMultiValueIdentifier
)identifier
{
NSLog
(
@"
选中联系人并调用该方法
"
);
}
//方法四
-
BOOL
)peoplePickerNavigationController:(
ABPeoplePickerNavigationController
*)peoplePicker shouldContinueAfterSelectingPerson:(
ABRecordRef
)person
{
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
;
}
主要调用的方法有方法一,方法四
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);
}
});
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);
}
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);
}
}