iOS之前是使用 AddressBook Framework 通路通訊錄,但從 iOS 9.0 開始被 Contacts Framework 替代,下面就看一下使用 AddressBook Framework 及 Contacts Framework 通路通訊錄
一、通路通訊錄及擷取聯系人
«« AddressBookFramework
/**
通路通訊錄
*/
- (void)requestAddressBookByAddressBookFramework {
_addressBookRef = ABAddressBookCreateWithOptions(nil, nil);
switch (ABAddressBookGetAuthorizationStatus()) {
/** 使用者拒絕或受限制直接傳回 */
case kABAuthorizationStatusDenied:
case kABAuthorizationStatusRestricted:
{
[self authorizedAlert];
}
break;
/** 未授權,請求授權 */
case kABAuthorizationStatusNotDetermined:
{
ABAddressBookRequestAccessWithCompletion(_addressBookRef, ^(bool granted, CFErrorRef error) {
if (!granted) {
[self authorizedAlert];
}else {
[self getAddressBook];
}
});
}
break;
/** 經授權,通路通訊錄 */
case kABAuthorizationStatusAuthorized:
{
[self getAddressBook];
}
break;
default:
break;
}
}
/**
讀取聯系人
*/
- (void)getAddressBook {
NSArray *peoples = (__bridge NSArray *)(ABAddressBookCopyArrayOfAllPeople(_addressBookRef));
_contactArray = [[NSMutableArray alloc] init];
for (int i = 0; i < peoples.count; i++) {
ABRecordRef people = (__bridge ABRecordRef)(peoples[i]);
NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty));
NSString *secondName = (__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
ABMultiValueRef phoneNums = ABRecordCopyValue(people, kABPersonPhoneProperty);
for (int i = 0; i < ABMultiValueGetCount(phoneNums); i++) {
ContactModel *contactModel = [[ContactModel alloc] init];
contactModel.name = [NSString stringWithFormat:@"%@%@", firstName ?: @"",secondName ?: @""];
contactModel.phoneNumber = [((__bridge NSString *)(ABMultiValueCopyValueAtIndex(phoneNums, i))) stringByReplacingOccurrencesOfString:@"-" withString:@""];
[_contactArray addObject:contactModel];
}
}
NSLog(@"%@", [_contactArray yy_modelToJSONObject]);
}
«« ContactsFramework
/**
請求通路通訊錄
*/
- (void)requestAddressBookByContactsFramework {
_contactStore = [[CNContactStore alloc] init];
switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]) {
/** 未授權,請求授權 */
case CNAuthorizationStatusNotDetermined:
{
[_contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted) {
[self authorizedAlert];
}else {
[self getContacts];
}
}];
}
break;
/** 使用者拒絕或受限制直接傳回 */
case CNAuthorizationStatusDenied:
case CNAuthorizationStatusRestricted:
{
[self authorizedAlert];
}
break;
/** 經授權,通路通訊錄 */
case CNAuthorizationStatusAuthorized:
{
[self getContacts];
}
break;
default:
break;
}
}
/**
擷取聯系人
*/
- (void)getContacts {
// 1. 建立聯系人資訊的請求對象
NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
// 2. 根據請求Key, 建立請求對象
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
_contactArray = [[NSMutableArray alloc] init];
//3. 請求聯系人資料
[_contactStore enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
NSArray<CNLabeledValue<CNPhoneNumber*>*> *phoneNumbers = contact.phoneNumbers;
for (CNLabeledValue *labeledValue in phoneNumbers) {
ContactModel *contactModel = [[ContactModel alloc] init];
contactModel.name = [NSString stringWithFormat:@"%@%@", contact.familyName ?: @"",contact.givenName ?: @""];
CNPhoneNumber *phoneNumber = labeledValue.value;
contactModel.phoneNumber = [[[phoneNumber.stringValue stringByReplacingOccurrencesOfString:@"-" withString:@""] stringByReplacingOccurrencesOfString:@"+86" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];
[_contactArray addObject:contactModel];
}
}];
NSLog(@"%@", [_contactArray yy_modelToJSONObject]);
}
其中 ContactModel 是為了在自定義界面上展示聯系人所建立的 model, authorizedAlert 為請求失敗時所彈的提示,如下
- (void)authorizedAlert {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示"
message:@"您目前未開啟擷取聯系人權限,請前往設定開啟權限"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"我知道了"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
[self.navigationController popViewControllerAnimated:YES];
}];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
二、對聯系人增删改查
1、增加聯系人
«« AddressBookFramework
«« ContactsFramework
/**
添加聯系人
*/
- (void)addContact {
CNMutableContact * contact = [[CNMutableContact alloc]init];
contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"guojing"]);
//設定名字
contact.givenName = @"金諾";
//設定姓氏
contact.familyName = @"郭";
contact.phoneNumbers = @[[CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberiPhone value:[CNPhoneNumber phoneNumberWithStringValue:@"12344312321"]]];
//初始化方法
CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
// 添加聯系人(可以)
[saveRequest addContact:contact toContainerWithIdentifier:nil];
// 寫入
[_contactStore executeSaveRequest:saveRequest error:nil];
[self getContacts];
}
2、更新聯系人
«« AddressBookFramework
«« ContactsFramework
/**
更新聯系人
*/
- (void)updateContact {
_contactStore = [[CNContactStore alloc] init];
//檢索條件,檢索所有名字中有zhang的聯系人
NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"金諾"];
//提取資料
NSArray * contacts = [_contactStore unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey, CNContactFamilyNameKey] error:nil];
for (CNContact *contact in contacts) {
CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
CNMutableContact *mutableContact = [contact mutableCopy];
mutableContact.familyName = @"慕容";
[saveRequest updateContact:mutableContact];
[_contactStore executeSaveRequest:saveRequest error:nil];
}
}
3、删除聯系人
«« AddressBookFramework
«« ContactsFramework
/**
删除聯系人
*/
- (void)deleteContact {
_contactStore = [[CNContactStore alloc] init];
//檢索條件,檢索所有名字中有zhang的聯系人
NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"金諾"];
//提取資料
NSArray * contacts = [_contactStore unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey, CNContactFamilyNameKey] error:nil];
for (CNContact *contact in contacts) {
CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
[saveRequest deleteContact:[contact mutableCopy]];
[_contactStore executeSaveRequest:saveRequest error:nil];
}
}