天天看點

AddressBook、AddressBookUI、Contacts、ContactsUI 通訊錄操作一、通路通訊錄及擷取聯系人二、對聯系人增删改查

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];
    }
}
           

繼續閱讀