iOS9.0新增了通訊錄類,按照一般教程使用即可完成通常的開發任務。在實際工作中,遇到了一個問題,如果通訊錄中存在某一個指定的姓名的聯系人,需要修改其聯系方式為XXXX-XXXXXX,不存在則創建這樣的一個聯系人。API中提供了updateContact方法,但直接調用會出現崩潰,原因是CNMutableContact的phoneNumbers的屬性為只讀,只有為空時才可以賦值。
所以解決這個問題的思路改為:如果存在該指定姓名的聯系人時,先刪除此聯系人,然后創建一個新的。
一、添加頭文件
#import <ContactsUI/ContactsUI.h>
二、常用API函數
2.1 獲取是否授權
//獲取是否授權
- (BOOL)getContactAuthorize:(CNContactStore *)contactStore {
__block BOOL grandted = YES;
[contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
grandted = YES;
}else {
grandted = NO;
}
}];
return grandted;
}
2.2 創建聯系人
/**
創建客服信息
*/
- (CNMutableContact *)crateServiceContact {
CNMutableContact *contact = [[CNMutableContact alloc] init];
contact.organizationName = KContactOrganizationName;
CNPhoneNumber *mobileNumber = [[CNPhoneNumber alloc] initWithStringValue:ServerPhoneNumber];
CNLabeledValue *mobilePhone = [[CNLabeledValue alloc] initWithLabel:CNLabelPhoneNumberMobile value:mobileNumber];
contact.phoneNumbers = @[mobilePhone];
return contact;
}
2.3 添加聯系人
/**
添加聯系人
*/
- (void)addContact:(CNMutableContact *)contact {
// 創建聯系人請求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
[saveRequest addContact:contact toContainerWithIdentifier:nil];
// 寫入聯系人
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:nil];
}
2.4 刪除聯系人
/**
刪除客服信息
*/
- (void)deleteContact:(CNMutableContact *)contact{
// 創建聯系人請求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
[saveRequest deleteContact:contact];
// 寫入操作
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:nil];
}
2.5判斷指定姓名聯系人是否存在
/**
判斷是否存在指定聯系人
*/
- (CNContact *)isExitContact:(NSString *)organizationName {
CNContactStore *store = [[CNContactStore alloc] init];
//檢索條件
NSPredicate *predicate = [CNContact predicateForContactsMatchingName:organizationName];
//過濾的條件
NSArray *keysToFetch = @[CNContactEmailAddressesKey, [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]];
NSArray *contact = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keysToFetch error:nil];
return [contact firstObject];
}
2.6 更新聯系人
/**
更新聯系人
*/
- (void)updateContact:(CNMutableContact *)contact{
// 創建聯系人請求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
[saveRequest updateContact:contact];
// 重新寫入
CNContactStore *store = [[CNContactStore alloc] init];
NSError *error = nil;
BOOL saveStatus = [store executeSaveRequest:saveRequest error:&error];
if (saveStatus == NO) {
NSLog(@"%@", error);
}
}
三、使用
使用上,需要先獲取授權信息,然后走不同的路徑。
/**
授權并新建聯系人到通訊錄
*/
+ (BOOL)createContact {
ZTEventKitManager *manager = [ZTEventKitManager sharedManager];
CNContactStore *contactStore = [[CNContactStore alloc] init];
switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]) {
case CNAuthorizationStatusNotDetermined:{
BOOL granted = [manager getContactAuthorize:contactStore];
if (granted) {
[manager updateContact];
return YES;
} else {
return NO;
}
}
case CNAuthorizationStatusAuthorized:{
[manager updateContact];
return YES;
}
default:
return NO;
break;
}
}
其中updateContact函數,作用是先判斷是否存在指定的聯系人如果存在,先刪除然后創建新的。
//更新聯系人信息
- (void)updateContact {
ZTEventKitManager *manager = [ZTEventKitManager sharedManager];
CNContact *contact = [manager isExitContact:KContactOrganizationName];
if (contact) {
CNMutableContact *contactOld= [contact mutableCopy];
[manager deleteContact:contactOld];
CNMutableContact *contactNew = [manager crateServiceContact];
[manager addContact:contactNew];
}else {
CNMutableContact *contact = [manager crateServiceContact];
[manager addContact:contact];
}
}