引言:這是我之前寫在博客園的一篇記錄筆記孵淘,因個(gè)人比較喜歡簡書的書寫環(huán)境與閱讀氣氛,所以統(tǒng)一整理到這里歹篓,做個(gè)備忘吧O(∩_∩)O哈哈~瘫证!
蘋果提供了訪問系統(tǒng)通訊錄的框架,以便開發(fā)者對系統(tǒng)通訊錄進(jìn)行操作庄撮。想要訪問通訊錄背捌,需要添加AddressBookUI.framework和AddressBook.framework兩個(gè)框架,添加的地點(diǎn)這里就不在贅述了。在控制器內(nèi)部首先import兩個(gè)頭文件洞斯,<AddressBook/AddressBook.h> 和 <AddressBookUI/AddressBookUI.h>毡庆,如下所示:
// ZBSampleViewController.m
// ZBAddressBookDemo
//
// Created by zhangb on 16/02/04.
// Copyright (c) 2016年 mbp. All rights reserved.
//
#import "ZBSampleViewController.h"
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
首先為了方便演示與操作,這里就以兩個(gè)按鈕的操作代替具體的訪問過程,當(dāng)然具體操作要具體分析么抗,這里只是記錄訪問通訊錄毅否,包括:
- 查看聯(lián)系人
- 向通訊錄內(nèi)添加聯(lián)系人。
下面是代碼示例:ABPeoplePickerNavigationController為展示系統(tǒng)通訊錄的控制器蝇刀,并且需要遵循其代理方法螟加。
- 向通訊錄內(nèi)添加聯(lián)系人。
#define IS_iOS8 [[UIDevice currentDevice].systemVersion floatValue] >= 8.0f
#define IS_iOS6 [[UIDevice currentDevice].systemVersion floatValue] >= 6.0f
@interface ZBSampleViewController ()<ABPeoplePickerNavigationControllerDelegate>{
ABPeoplePickerNavigationController *_abPeoplePickerVc;
NSMutableDictionary *_infoDictionary;
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
//1.打開通訊錄
UIButton *openAddressBook = [UIButton buttonWithType:UIButtonTypeCustom];
openAddressBook.frame = CGRectMake(100, 50, 100, 50);
[openAddressBook setTitle:@"打開通訊錄" forState:UIControlStateNormal];
openAddressBook.backgroundColor = [UIColor greenColor];
[openAddressBook setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[openAddressBook addTarget:self action:@selector(gotoAddressBook) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:openAddressBook];
//2.添加聯(lián)系人
UIButton *addContacts = [UIButton buttonWithType:UIButtonTypeCustom];
addContacts.frame = CGRectMake(100, 150, 100, 50);
[addContacts setTitle:@"添加聯(lián)系人" forState:UIControlStateNormal];
addContacts.backgroundColor = [UIColor greenColor];
[addContacts setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[addContacts addTarget:self action:@selector(gotoAddContacts) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:addContacts];
}
打開系統(tǒng)通訊錄方法為openAddressBook按鈕的點(diǎn)擊事件,請忽略按鈕的樣式O(∩_∩)O~吞琐;
下面的IS_iOS8為我定義的宏仰迁,判斷系統(tǒng)的版本(上面有代碼示例)。
/**
打開通訊錄
*/
- (void)gotoAddressBook{
_abPeoplePickerVc = [[ABPeoplePickerNavigationController alloc] init];
_abPeoplePickerVc.peoplePickerDelegate = self;
//下面的判斷是ios8之后才需要加的顽分,不然會自動返回app內(nèi)部
if(IS_iOS8){
//predicateForSelectionOfPerson默認(rèn)是true (當(dāng)你點(diǎn)擊某個(gè)聯(lián)系人查看詳情的時(shí)候會返回app),如果你默認(rèn)為true 但是實(shí)現(xiàn)-peoplePickerNavigationController:didSelectPerson:property:identifier:代理方法也是可以的施蜜,與此同時(shí)不能實(shí)現(xiàn)peoplePickerNavigationController: didSelectPerson:不然還是會返回app卒蘸。
//總之在ios8之后加上此句比較穩(wěn)妥
_abPeoplePickerVc.predicateForSelectionOfPerson = [NSPredicate predicateWithValue:false];
// predicateForSelectionOfProperty默認(rèn)是true (當(dāng)你點(diǎn)擊某個(gè)聯(lián)系人的某個(gè)屬性的時(shí)候會返回app),此方法只要是默認(rèn)值翻默,無論你代理方法實(shí)現(xiàn)與否都會返回app缸沃。
_abPeoplePickerVc.predicateForSelectionOfProperty = [NSPredicate predicateWithValue:false];
//predicateForEnablingPerson默認(rèn)是true,當(dāng)設(shè)置為false時(shí)修械,所有的聯(lián)系人都不能被點(diǎn)擊趾牧。
// _abPeoplePickerVc.predicateForEnablingPerson = [NSPredicate predicateWithValue:true];
}
[self presentViewController:_abPeoplePickerVc animated:YES completion:nil];
}
這里需要注意的是:
在iOS8之后需要加_abPeoplePickerVc.predicateForSelectionOfPerson = [NSPredicate predicateWithValue:false];
這句代碼,不然當(dāng)你選擇通訊錄中的某個(gè)聯(lián)系人的時(shí)候會直接返回app內(nèi)部(類似crash)肯污。predicateForSelectionOfPerson默認(rèn)是true (當(dāng)你點(diǎn)擊某個(gè)聯(lián)系人查看詳情的時(shí)候會返回app)翘单,如果你默認(rèn)為true 但是實(shí)現(xiàn)-peoplePickerNavigationController:didSelectPerson:property:identifier:
代理方法也是可以的,與此同時(shí)不能實(shí)現(xiàn)peoplePickerNavigationController: didSelectPerson:
不然還是會返回app蹦渣。_abPeoplePickerVc.predicateForSelectionOfProperty = [NSPredicate predicateWithValue:false];
作用同上哄芜。但是_abPeoplePickerVc.predicateForEnablingPerson 的斷言語句必須為true,否則任何聯(lián)系人你都不能選擇柬唯。上面的代碼中也有詳細(xì)描述认臊。
#pragma mark - ABPeoplePickerNavigationController的代理方法
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);
long index = ABMultiValueGetIndexForIdentifier(phone,identifier);
NSString *phoneNO = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phone, index);
[phoneNO stringByReplacingOccurrencesOfString:@"-" withString:@""];
if (phone && phoneNO.length == 11) {
//TODO:獲取電話號碼要做的事情
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
return;
}else{
if (IS_iOS8){
UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:nil message:@"請選擇正確手機(jī)號" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[tipVc addAction:cancleAction];
[self presentViewController:tipVc animated:YES completion:nil];
}else{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"請選擇正確手機(jī)號" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil];
[alertView show];
}
//非ARC模式需要釋放對象
// [alertView release];
}
}
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person NS_AVAILABLE_IOS(8_0)
{
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.displayedPerson = person;
[peoplePicker pushViewController:personViewController animated:YES];
//非ARC模式需要釋放對象
// [personViewController release];
}
/**
peoplePickerNavigationController點(diǎn)擊取消按鈕時(shí)調(diào)用
*/
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
}
/**
iOS8被廢棄了,iOS8前查看聯(lián)系人必須實(shí)現(xiàn)(點(diǎn)擊聯(lián)系人可以繼續(xù)操作)
*/
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person NS_DEPRECATED_IOS(2_0, 8_0)
{
return YES;
}
/**
iOS8被廢棄了锄奢,iOS8前查看聯(lián)系人屬性必須實(shí)現(xiàn)(點(diǎn)擊聯(lián)系人屬性可以繼續(xù)操作)
*/
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier NS_DEPRECATED_IOS(2_0, 8_0)
{
ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);
long index = ABMultiValueGetIndexForIdentifier(phone,identifier);
NSString *phoneNO = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phone, index);
phoneNO = [phoneNO stringByReplacingOccurrencesOfString:@"-" withString:@""];
NSLog(@"%@", phoneNO);
if (phone && phoneNO.length == 11) {
//TODO:獲取電話號碼要做的事情
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
return NO;
}else{
if (IS_iOS8){
UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:nil message:@"請選擇正確手機(jī)號" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[tipVc addAction:cancleAction];
[self presentViewController:tipVc animated:YES completion:nil];
}else{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"請選擇正確手機(jī)號" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil];
[alertView show];
}
}
return YES;
}
ABPeoplePickerNavigationController的代理方法也很好理解失晴,看字面意思就能夠猜出代理方法的執(zhí)行時(shí)間與能夠做什么。拿第一個(gè)代理方法說明一下拘央,也就是- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier涂屁;
第一個(gè)參數(shù)就不用說了,第二個(gè)參數(shù)ABRecordRef 這是一個(gè)聯(lián)系人的引用也可以說是一個(gè)記錄堪滨,你可以理解為一個(gè)聯(lián)系人胯陋。第三個(gè)參數(shù)是聯(lián)系人附帶屬性的ID,其實(shí)ABPropertyID是個(gè)int類型值。第四個(gè)參數(shù)是多值屬性的標(biāo)簽遏乔。
ABRecordCopyValue(ABRecordRef record, ABPropertyID property)返回一個(gè)CFTypeRef類型义矛。此方法是從系統(tǒng)的通訊錄內(nèi),copy出用戶所選擇的某個(gè)聯(lián)系人數(shù)據(jù)盟萨。返回類型要看參數(shù)傳遞的是什么凉翻,第一個(gè)參數(shù)是聯(lián)系人記錄,第二個(gè)參數(shù)是參數(shù)ID捻激,也就是用戶選擇的聯(lián)系人的某個(gè)屬性的ID制轰。kABPersonPhoneProperty代表的是手機(jī)號碼屬性的ID,假如上面的ABRecordCopyValue的第二個(gè)參數(shù)傳遞kABPersonAddressProperty胞谭,則返回的是聯(lián)系人的地址屬性垃杖。下面是效果圖(因?yàn)槭悄M器和真機(jī)有些差異)。
下面介紹下丈屹,向系統(tǒng)通訊錄內(nèi)添加聯(lián)系人调俘。這里我只設(shè)置了聯(lián)系人的三個(gè)屬性:名字,電話旺垒,郵件彩库,并將屬性存在了字典里。
-(instancetype)init{
if (self = [super init]) {
_infoDictionary = [NSMutableDictionary dictionaryWithCapacity:0];
[_infoDictionary setObject:@"張三" forKey:@"name"];
[_infoDictionary setObject:@"13000000000" forKey:@"phone"];
[_infoDictionary setObject:@"1000000000@qq.com" forKey:@"email"];
}
return self;
}
因?yàn)樘O果越來越注重保護(hù)用戶的隱私先蒋,現(xiàn)在需要修改系統(tǒng)通訊錄內(nèi)的聯(lián)系人信息時(shí)骇钦,必須要用戶授權(quán)才可以進(jìn)行。授權(quán)鑒定代碼為:
ABAddressBookRequestAccessWith
Completion
(ABAddressBookRef addressBook,
ABAddressBookRequestAccessCompletionHandler completion)__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);
下面的代碼中都有詳細(xì)描述竞漾。
/**
添加聯(lián)系人
*/
- (void)gotoAddContacts{
//添加到通訊錄,判斷通訊錄是否存在
if ([self isExistContactPerson]) {//存在眯搭,返回
//提示
if (IS_iOS8) {
UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:@"提示" message:@"聯(lián)系人已存在..." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[tipVc addAction:cancleAction];
[self presentViewController:tipVc animated:YES completion:nil];
}else{
UIAlertView *tip = [[UIAlertView alloc] initWithTitle:@"提示" message:@"聯(lián)系人已存在..." delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[tip show];
// [tip release];
}
return;
}else{//不存在 添加
[self creatNewRecord];
}
}
- (BOOL)isExistContactPerson{
//這個(gè)變量用于記錄授權(quán)是否成功,即用戶是否允許我們訪問通訊錄
int __block tip=0;
BOOL __block isExist = NO;
//聲明一個(gè)通訊簿的引用
ABAddressBookRef addBook =nil;
//因?yàn)樵贗OS6.0之后和之前的權(quán)限申請方式有所差別业岁,這里做個(gè)判斷
if (IS_iOS6) {
//創(chuàng)建通訊簿的引用坦仍,第一個(gè)參數(shù)暫時(shí)寫NULL,官方文檔就是這么說的叨襟,后續(xù)會有用繁扎,第二個(gè)參數(shù)是error參數(shù)
CFErrorRef error = NULL;
addBook=ABAddressBookCreateWithOptions(NULL, &error);
//創(chuàng)建一個(gè)初始信號量為0的信號
dispatch_semaphore_t sema=dispatch_semaphore_create(0);
//申請?jiān)L問權(quán)限
ABAddressBookRequestAccessWithCompletion(addBook, ^(bool greanted, CFErrorRef error) {
//greanted為YES是表示用戶允許,否則為不允許
if (!greanted) {
tip=1;
}else{
//獲取所有聯(lián)系人的數(shù)組
CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addBook);
//獲取聯(lián)系人總數(shù)
CFIndex number = ABAddressBookGetPersonCount(addBook);
//進(jìn)行遍歷
for (NSInteger i=0; i<number; i++) {
//獲取聯(lián)系人對象的引用
ABRecordRef people = CFArrayGetValueAtIndex(allLinkPeople, i);
//獲取當(dāng)前聯(lián)系人名字
NSString*firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
if ([firstName isEqualToString:[_infoDictionary objectForKey:@"name"]]) {
isExist = YES;
}
// //獲取當(dāng)前聯(lián)系人姓氏
// NSString*lastName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty));
//獲取當(dāng)前聯(lián)系人中間名
// NSString*middleName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNameProperty));
// //獲取當(dāng)前聯(lián)系人的名字前綴
// NSString*prefix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonPrefixProperty));
// //獲取當(dāng)前聯(lián)系人的名字后綴
// NSString*suffix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonSuffixProperty));
// //獲取當(dāng)前聯(lián)系人的昵稱
// NSString*nickName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNicknameProperty));
// //獲取當(dāng)前聯(lián)系人的名字拼音
// NSString*firstNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonFirstNamePhoneticProperty));
// //獲取當(dāng)前聯(lián)系人的姓氏拼音
// NSString*lastNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonLastNamePhoneticProperty));
// //獲取當(dāng)前聯(lián)系人的中間名拼音
// NSString*middleNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNamePhoneticProperty));
// //獲取當(dāng)前聯(lián)系人的公司
// NSString*organization=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonOrganizationProperty));
// //獲取當(dāng)前聯(lián)系人的職位
// NSString*job=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonJobTitleProperty));
// //獲取當(dāng)前聯(lián)系人的部門
// NSString*department=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonDepartmentProperty));
// //獲取當(dāng)前聯(lián)系人的生日
// NSString*birthday=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonBirthdayProperty));
// NSMutableArray * emailArr = [[NSMutableArray alloc]init];
// //獲取當(dāng)前聯(lián)系人的郵箱 注意是數(shù)組
// ABMultiValueRef emails= ABRecordCopyValue(people, kABPersonEmailProperty);
// for (NSInteger j=0; j<ABMultiValueGetCount(emails); j++) {
// [emailArr addObject:(__bridge NSString *)(ABMultiValueCopyValueAtIndex(emails, j))];
// }
// //獲取當(dāng)前聯(lián)系人的備注
// NSString*notes=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNoteProperty));
// //獲取當(dāng)前聯(lián)系人的電話 數(shù)組
// NSMutableArray * phoneArr = [[NSMutableArray alloc]init];
// ABMultiValueRef phones= ABRecordCopyValue(people, kABPersonPhoneProperty);
// for (NSInteger j=0; j<ABMultiValueGetCount(phones); j++) {
// [phoneArr addObject:(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phones, j))];
// }
// //獲取創(chuàng)建當(dāng)前聯(lián)系人的時(shí)間 注意是NSDate
// NSDate*creatTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonCreationDateProperty));
// //獲取最近修改當(dāng)前聯(lián)系人的時(shí)間
// NSDate*alterTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonModificationDateProperty));
// //獲取地址
// ABMultiValueRef address = ABRecordCopyValue(people, kABPersonAddressProperty);
// for (int j=0; j<ABMultiValueGetCount(address); j++) {
// //地址類型
// NSString * type = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(address, j));
// NSDictionary * temDic = (__bridge NSDictionary *)(ABMultiValueCopyValueAtIndex(address, j));
// //地址字符串糊闽,可以按需求格式化
// NSString * adress = [NSString stringWithFormat:@"國家:%@\n省:%@\n市:%@\n街道:%@\n郵編:%@",[temDic valueForKey:(NSString*)kABPersonAddressCountryKey],[temDic valueForKey:(NSString*)kABPersonAddressStateKey],[temDic valueForKey:(NSString*)kABPersonAddressCityKey],[temDic valueForKey:(NSString*)kABPersonAddressStreetKey],[temDic valueForKey:(NSString*)kABPersonAddressZIPKey]];
// }
// //獲取當(dāng)前聯(lián)系人頭像圖片
// NSData*userImage=(__bridge NSData*)(ABPersonCopyImageData(people));
// //獲取當(dāng)前聯(lián)系人紀(jì)念日
// NSMutableArray * dateArr = [[NSMutableArray alloc]init];
// ABMultiValueRef dates= ABRecordCopyValue(people, kABPersonDateProperty);
// for (NSInteger j=0; j<ABMultiValueGetCount(dates); j++) {
// //獲取紀(jì)念日日期
// NSDate * data =(__bridge NSDate*)(ABMultiValueCopyValueAtIndex(dates, j));
// //獲取紀(jì)念日名稱
// NSString * str =(__bridge NSString*)(ABMultiValueCopyLabelAtIndex(dates, j));
// NSDictionary * temDic = [NSDictionary dictionaryWithObject:data forKey:str];
// [dateArr addObject:temDic];
// }
}
}
//發(fā)送一次信號
dispatch_semaphore_signal(sema);
});
//等待信號觸發(fā)
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}else{
//IOS6之前
addBook =ABAddressBookCreate();
//獲取所有聯(lián)系人的數(shù)組
CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addBook);
//獲取聯(lián)系人總數(shù)
CFIndex number = ABAddressBookGetPersonCount(addBook);
//進(jìn)行遍歷
for (NSInteger i=0; i<number; i++) {
//獲取聯(lián)系人對象的引用
ABRecordRef people = CFArrayGetValueAtIndex(allLinkPeople, i);
//獲取當(dāng)前聯(lián)系人名字
NSString*firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
if ([firstName isEqualToString:[_infoDictionary objectForKey:@"name"]]) {
isExist = YES;
}
}
}
if (tip) {
//設(shè)置提示
if (IS_iOS8) {
UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:@"友情提示" message:@"請您設(shè)置允許APP訪問您的通訊錄\nSettings>General>Privacy" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[tipVc addAction:cancleAction];
[tipVc presentViewController:tipVc animated:YES completion:nil];
}else{
UIAlertView * alart = [[UIAlertView alloc]initWithTitle:@"友情提示" message:@"請您設(shè)置允許APP訪問您的通訊錄\nSettings>General>Privacy" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alart show];
//非ARC
// [alart release];
}
}
return isExist;
}
//創(chuàng)建新的聯(lián)系人
- (void)creatNewRecord
{
CFErrorRef error = NULL;
//創(chuàng)建一個(gè)通訊錄操作對象
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
//創(chuàng)建一條新的聯(lián)系人紀(jì)錄
ABRecordRef newRecord = ABPersonCreate();
//為新聯(lián)系人記錄添加屬性值
ABRecordSetValue(newRecord, kABPersonFirstNameProperty, (__bridge CFTypeRef)[_infoDictionary objectForKey:@"name"], &error);
//創(chuàng)建一個(gè)多值屬性(電話)
ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(multi, (__bridge CFTypeRef)[_infoDictionary objectForKey:@"phone"], kABPersonPhoneMobileLabel, NULL);
ABRecordSetValue(newRecord, kABPersonPhoneProperty, multi, &error);
//添加email
ABMutableMultiValueRef multiEmail = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(multiEmail, (__bridge CFTypeRef)([_infoDictionary objectForKey:@"email"]), kABWorkLabel, NULL);
ABRecordSetValue(newRecord, kABPersonEmailProperty, multiEmail, &error);
//添加記錄到通訊錄操作對象
ABAddressBookAddRecord(addressBook, newRecord, &error);
//保存通訊錄操作對象
ABAddressBookSave(addressBook, &error);
//通過此接口訪問系統(tǒng)通訊錄
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
//顯示提示
if (IS_iOS8) {
UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:@"添加成功" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[alertVc addAction:alertAction];
[self presentViewController:alertVc animated:YES completion:nil];
}else{
UIAlertView *tipView = [[UIAlertView alloc] initWithTitle:nil message:@"添加成功" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
[tipView show];
//非ARC
// [tipView release];
}
}
});
CFRelease(multiEmail);
CFRelease(multi);
CFRelease(newRecord);
CFRelease(addressBook);
}
代碼中有每個(gè)步驟都有對應(yīng)的注釋梳玫,對應(yīng)看起來會容易一些!下面是效果圖:
如果需要添加聯(lián)系人的其他屬性右犹,方法類似提澎,只是屬性名不同。慢慢挖掘吧念链,伙伴們盼忌!
聲明:此文僅為了記錄本人開發(fā)中的遇到并解決的問題积糯,權(quán)當(dāng)是一篇筆記,并不是教學(xué)blog谦纱,不免會有錯誤看成,如有煩請指正,大家共同學(xué)習(xí)跨嘉!謝謝川慌!
下面列舉一些參考blog:(再次感謝無私分享的coder)
http://m.open-open.com/m/code/view/1432302834146
http://supershll.blog.163.com/blog/static/37070436201272821810474/
http://www.tuicool.com/articles/Mvuu6z
注意:iOS10以及Xcode8的緣故,需要適配祠乃,需要添加訪問權(quán)限設(shè)置梦重,也就是在info.plist中添加key:Privacy - Contacts Usage Description value:對應(yīng)的value值可以隨便寫,不然程序會崩潰亮瓷!