Contacts 通讯录

1、访问通讯录

  • 设置系统访问通讯录权限

1.1 iOS 9.0 及 iOS 9.0 之后获取通讯录的方法

  • iOS 9.0 及 iOS 9.0 之后获取通讯录的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    // 包含头文件
    #import <Contacts/Contacts.h>
    #import <ContactsUI/ContactsUI.h>

    // 获取通讯录信息,自定义方法
    - (void)fetchAddressBookOnIOS9AndLater {

    // 创建 CNContactStore 对象
    CNContactStore *contactStore = [[CNContactStore alloc] init];

    // 首次访问需用户授权
    if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusNotDetermined) {

    // 首次访问通讯录

    [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {

    if (!error){

    if (granted) {

    // 允许

    NSLog(@"已授权访问通讯录");
    NSArray *contacts = [self fetchContactWithContactStore:contactStore]; // 访问通讯录

    dispatch_async(dispatch_get_main_queue(), ^{

    // 主线程 更新 UI
    NSLog(@"contacts:%@", contacts);

    });

    } else {

    // 拒绝

    NSLog(@"拒绝访问通讯录");
    }

    } else {
    NSLog(@"发生错误!");
    }
    }];

    } else {

    // 非首次访问通讯录

    NSArray *contacts = [self fetchContactWithContactStore:contactStore]; // 访问通讯录
    dispatch_async(dispatch_get_main_queue(), ^{

    // 主线程 更新 UI
    NSLog(@"contacts:%@", contacts);

    });
    }
    }

    // 访问通讯录,自定义方法
    - (NSMutableArray *)fetchContactWithContactStore:(CNContactStore *)contactStore {

    // 判断访问权限
    if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusAuthorized) {

    // 有权限访问
    NSError *error = nil;

    // 创建数组,必须遵守 CNKeyDescriptor 协议,放入相应的字符串常量来获取对应的联系人信息
    NSArray <id<CNKeyDescriptor>> *keysToFetch = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey];

    // 获取通讯录数组
    NSArray<CNContact*> *arr = [contactStore unifiedContactsMatchingPredicate:nil keysToFetch:keysToFetch error:&error];

    if (!error) {

    NSMutableArray *contacts = [NSMutableArray array];
    for (int i = 0; i < arr.count; i++) {

    CNContact *contact = arr[i];
    NSString *givenName = contact.givenName;
    NSString *familyName = contact.familyName;
    NSString *phoneNumber = ((CNPhoneNumber *)(contact.phoneNumbers.lastObject.value)).stringValue;

    [contacts addObject:@{@"name":[givenName stringByAppendingString:familyName], @"phoneNumber":phoneNumber}];
    }
    return contacts;

    } else {
    return nil;
    }

    } else {

    // 无权限访问
    NSLog(@"无权限访问通讯录");

    return nil;
    }
    }
    • 效果

1.2 iOS 9.0 之前获取通讯录的方法

  • iOS 9.0 之前获取通讯录的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    // 包含头文件
    #import <AddressBook/AddressBook.h>

    // 获取通讯录信息,自定义方法
    - (void)fetchAddressBookBeforeIOS9 {

    ABAddressBookRef addressBook = ABAddressBookCreate();

    // 首次访问需用户授权
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {

    // 首次访问通讯录

    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {

    if (!error) {

    if (granted) {

    // 允许

    NSLog(@"已授权访问通讯录");
    NSArray *contacts = [self fetchContactWithAddressBook:addressBook];

    dispatch_async(dispatch_get_main_queue(), ^{

    // 主线程 更新 UI
    NSLog(@"contacts:%@", contacts);

    });

    } else {

    // 拒绝

    NSLog(@"拒绝访问通讯录");
    }

    } else {
    NSLog(@"发生错误!");
    }
    });
    } else {

    // 非首次访问通讯录

    NSArray *contacts = [self fetchContactWithAddressBook:addressBook];

    dispatch_async(dispatch_get_main_queue(), ^{

    // 主线程 更新 UI
    NSLog(@"contacts:%@", contacts);

    });
    }
    }

    // 访问通讯录,自定义方法
    - (NSMutableArray *)fetchContactWithAddressBook:(ABAddressBookRef)addressBook {

    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {

    // 有权限访问

    // 获取联系人数组
    NSArray *array = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);

    NSMutableArray *contacts = [NSMutableArray array];
    for (int i = 0; i < array.count; i++) {

    //获取联系人
    ABRecordRef people = CFArrayGetValueAtIndex((__bridge ABRecordRef)array, i);

    // 获取联系人详细信息,如:姓名,电话,住址等信息
    NSString *firstName = (__bridge NSString *)ABRecordCopyValue(people, kABPersonFirstNameProperty);
    NSString *lastName = (__bridge NSString *)ABRecordCopyValue(people, kABPersonLastNameProperty);
    ABMutableMultiValueRef *phoneNumRef = ABRecordCopyValue(people, kABPersonPhoneProperty);
    NSString *phoneNumber = ((__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneNumRef)).lastObject;

    [contacts addObject:@{@"name": [firstName stringByAppendingString:lastName], @"phoneNumber": phoneNumber}];
    }
    return contacts;

    } else {

    // 无权限访问

    NSLog(@"无权限访问通讯录");

    return nil;
    }
    }
    • 效果

2、对通讯录的操作

  • 对通讯录的操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 包含头文件
    #import <Contacts/Contacts.h>
    #import <ContactsUI/ContactsUI.h>

    // 遵守协议
    <CNContactPickerDelegate>

    @property (nonatomic, strong) NSArray *contacts;
    @property (nonatomic, strong) NSArray *groups;

2.1 打开通讯录

  • 打开通讯录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    // 初始化 CNContactPickerViewController
    CNContactPickerViewController *contactPickerVC = [[CNContactPickerViewController alloc] init];

    // 设置代理,需遵守 CNContactPickerDelegate 协议
    contactPickerVC.delegate = self;

    // 显示联系人窗口视图
    [self presentViewController:contactPickerVC animated:YES completion:nil];

    // 取消,CNContactPickerDelegate 协议方法
    - (void)contactPickerDidCancel:(CNContactPickerViewController *)picker {

    // 点击联系人控制器的 Cancel 按钮执行该方法,picker 联系人控制器

    NSLog(@"取消");
    }

    // 选中联系人,CNContactPickerDelegate 协议方法
    - (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact {

    // 选中联系人时执行该方法,picker 联系人控制器,contact 联系人

    NSLog(@"联系人的资料:%@", contact);
    [self dismissViewControllerAnimated:YES completion:nil];

    // 显示联系人详细页面
    CNContactViewController *contactVC = [CNContactViewController viewControllerForContact:contact];

    contactVC.displayedPropertyKeys = @[CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactFamilyNameKey,
    CNContactInstantMessageAddressesKey, CNContactEmailAddressesKey,
    CNContactDatesKey, CNContactUrlAddressesKey, CNContactBirthdayKey,
    CNContactImageDataKey];

    [self presentViewController:contactVC animated:YES completion:nil];
    }

2.2 联系人操作

  • 1、增加联系人

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    // 增加的联系人信息
    CNMutableContact *contact = [self initializeContact];

    // 创建请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];

    // 添加联系人
    [saveRequest addContact:contact toContainerWithIdentifier:nil];

    // 同步到通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    [store executeSaveRequest:saveRequest error:NULL];

    // 初始化联系人信息
    - (CNMutableContact *)initializeContact {

    // 创建联系人对象
    CNMutableContact *contact = [[CNMutableContact alloc] init];

    // 设置联系人的头像
    contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"demo5"]);

    // 设置联系人姓名
    contact.givenName = @"Qian";

    // 设置姓氏
    contact.familyName = @"Chia";

    // 设置联系人邮箱
    CNLabeledValue *homeEmail = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:@"qianchia@icloud.com"];
    CNLabeledValue *workEmail = [CNLabeledValue labeledValueWithLabel:CNLabelWork value:@"qianchia@icloud.com"];
    CNLabeledValue *otherEmail = [CNLabeledValue labeledValueWithLabel:CNLabelOther value:@"qianchia@icloud.com"];
    contact.emailAddresses = @[homeEmail,workEmail,otherEmail];

    // 设置机构名
    contact.organizationName = @"互联网";

    // 设置部门
    contact.departmentName = @"Development";

    // 设置工作的名称
    contact.jobTitle = @"iOS";

    // 设置社会的简述
    CNSocialProfile *profile = [[CNSocialProfile alloc] initWithUrlString:@"12306.cn" username:@"lily" userIdentifier:nil service:@"IT行业"];
    CNLabeledValue *socialProfile = [CNLabeledValue labeledValueWithLabel:CNSocialProfileServiceGameCenter value:profile];
    contact.socialProfiles = @[socialProfile];

    // 设置电话号码
    CNPhoneNumber *mobileNumber = [[CNPhoneNumber alloc] initWithStringValue:@"15188888888"];
    CNLabeledValue *mobilePhone = [[CNLabeledValue alloc] initWithLabel:CNLabelPhoneNumberMobile value:mobileNumber];
    contact.phoneNumbers = @[mobilePhone];

    // 设置与联系人的关系
    CNContactRelation *friend = [[CNContactRelation alloc] initWithName:@"好朋友"];
    CNLabeledValue *relation = [CNLabeledValue labeledValueWithLabel:CNLabelContactRelationFriend value:friend];
    contact.contactRelations = @[relation];

    // 设置生日
    NSDateComponents *birthday = [[NSDateComponents alloc] init];
    birthday.day = 6;
    birthday.month = 5;
    birthday.year = 2000;
    contact.birthday = birthday;

    return contact;
    }
  • 2、删除联系人

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 要删除的联系人
    CNMutableContact *contact = [self.contacts[0] mutableCopy];

    // 创建请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];

    // 删除联系人
    [saveRequest deleteContact:contact];

    // 同步到通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    [store executeSaveRequest:saveRequest error:NULL];
  • 3、修改联系人

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 要修改的联系人信息
    CNMutableContact *contact = [self.contacts[0] mutableCopy];
    contact.givenName = @"Qianqian";

    // 创建请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];

    // 修改联系人
    [saveRequest updateContact:contact];

    // 同步到通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    [store executeSaveRequest:saveRequest error:NULL];
  • 4、查询联系人

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 要查询的联系人 GivenName
    NSString *checkName = @"Qian";

    // 检索条件
    NSPredicate *predicate = [CNContact predicateForContactsMatchingName:checkName];

    // 提取数据 (keysToFetch:@[CNContactGivenNameKey] 是设置提取联系人的哪些数据)
    CNContactStore *store = [[CNContactStore alloc] init];
    NSArray *contactArray = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:NULL];

    self.contacts = contactArray;

2.3 联系人群组操作

  • 1、增加群组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 要增加的群组
    CNMutableGroup *group = [[CNMutableGroup alloc] init];
    group.name = @"QianFriend";

    // 创建请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];

    // 增加群组
    [saveRequest addGroup:group toContainerWithIdentifier:nil];

    // 同步到通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    [store executeSaveRequest:saveRequest error:NULL];
  • 2、删除群组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 要删除的群组
    CNMutableGroup *group = self.groups[0];

    // 创建请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];

    // 删除群组
    [saveRequest deleteGroup:group];

    // 同步到通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    [store executeSaveRequest:saveRequest error:NULL];
  • 3、修改群组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 要修改的群组
    CNMutableGroup *group = self.groups[0];
    group.name = @"QianWork";

    // 创建请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];

    // 修改群组
    [saveRequest updateGroup:group];

    // 同步到通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    [store executeSaveRequest:saveRequest error:NULL];
  • 4、查询群组

    1
    2
    3
    4
    5
    6
    CNContactStore *store = [[CNContactStore alloc] init];

    // 查询所有的 group(predicate 参数为空时会查询所有的 group)
    NSArray *groupArray = [store groupsMatchingPredicate:nil error:NULL];

    self.groups = groupArray;
  • 5、向群组中添加联系人

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 要添加的联系人和群组
    CNContact *contact = self.contacts[0];
    CNMutableGroup *group = self.groups[0];

    // 创建请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];

    // 向群组中添加联系人
    [saveRequest addMember:contact toGroup:group];

    // 同步到通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    [store executeSaveRequest:saveRequest error:NULL];
  • 6、从群组中删除联系人

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 要删除的联系人和群组
    CNContact *contact = self.contacts[0];
    CNMutableGroup *group = self.groups[0];

    // 创建请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];

    // 从群组中删除联系人
    [saveRequest removeMember:contact fromGroup:group];

    // 同步到通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    [store executeSaveRequest:saveRequest error:NULL];
文章目录
  1. 1. 1、访问通讯录
    1. 1.1. 1.1 iOS 9.0 及 iOS 9.0 之后获取通讯录的方法
    2. 1.2. 1.2 iOS 9.0 之前获取通讯录的方法
  2. 2. 2、对通讯录的操作
    1. 2.1. 2.1 打开通讯录
    2. 2.2. 2.2 联系人操作
    3. 2.3. 2.3 联系人群组操作
隐藏目录