目录

前言

1.什么是CNContactStore

2.获取通讯录权限

1.配置plist文件

2.请求访问通讯录授权

3.通讯录访问权限的其它配置       

3.获取通讯录中的联系人

4.获取通讯录中的群组

5.操作联系人

1.增加联系人

2.更新联系人信息

3.删除联系人信息

6.监听通讯录变化

8.参考文章


前言

    iOS中通讯录的用法。

1.什么是CNContactStore

        CNContactStore类是iOS中的一个框架,用于访问和管理设备上的通讯录数据。它提供了一种统一的方式来获取、添加、更新和删除联系人和群组,以及监听通讯录数据的变化。在iOS开发中,CNContactStore类具有重要性,因为它允许应用程序与设备上的通讯录进行交互,从而实现诸如获取联系人信息、同步联系人数据、发送通讯录相关的通知等功能。通过CNContactStore类,开发人员可以轻松地构建与通讯录相关的功能,提高应用程序的用户体验和功能性。

2.获取通讯录权限

        因为手机通讯录信息数据敏感信息,因此我们需要请求用户的授权。在用户未授权我们的app访问通讯录权限之前,app无法请求通讯录信息。描述要简单、清晰,让用户有信心授权app访问。

        请求用户授权访问手机通讯录之前,我们按照下面的步骤配置app项目。

1.配置plist文件

        首先我们需要再项目的plist文件中添加NSContactsUsageDescription属性,这个key对应的值用来描述app要执行的操作以及我们为什么要请求用户授权访问通讯录。如果没有配置这个key,app请求通讯录的时候,程序会终止。

2.请求访问通讯录授权

        我们先看下通讯录权限状态的类型定义,通讯类权限状态是一个CNAuthorizationStatus类型的枚举,定义如下:

        这里需要注意的是只有当通讯录授权状态为CNAuthorizationStatusNotDetermined的时候,系统才会向用户展示一个弹窗,让用户选择是否授权app访问通讯录权限。其它状态下,系统不会再展示让用户选择是否授权状态的弹窗。

        app调用requestAccessForEntityType:completionHandler类方法,返回当前通讯录的授权状态。demo如下:

- (void)requestContactAccess{
    // 检查授权状态
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    // 请求授权
    // 请求授权
    if (status == CNAuthorizationStatusNotDetermined) {
        CNContactStore *store = [[CNContactStore alloc] init];
        [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                // 用户授予了授权,可以继续访问通讯录数据
                NSLog(@"用户已授权访问通讯录");
            } else {
                // 用户拒绝了授权,需要适当地处理这种情况
                NSLog(@"用户拒绝了访问通讯录的授权请求");
            }
        }];
    } else if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusRestricted) {
        // 用户已经拒绝了授权或者授权受限,需要适当地处理这种情况
        NSLog(@"用户拒绝了访问通讯录的授权请求");
    } else {
        // 用户已经授予了授权,可以继续访问通讯录数据
        NSLog(@"用户已授权访问通讯录");
    }
}

3.通讯录访问权限的其它配置       

        如果我们需要再iOS13以及之后的版本读写联系人字段的时候,需要添加权限到app,得到apple的许可才能时候,在未得到Apple许可之前,是无法分发app的。具体的配置看这里

        文档很详细,因为暂时没有发布app的需求,这个就不详细描述了。

3.获取通讯录中的联系人

        获取通讯录我们可以使用CNContactStore类,CNContactStore类是iOS中用于访问和操作通讯录数据的主要接口之一。它提供了一组方法来执行各种通讯录操作,包括读取、写入、更新和删除联系人、群组等。

        获取通讯录中的联系人信息的时候,我们需要使用CNContactFetchRequest创建通讯录请求。使用步骤如下:

        1.实例化CNContactStore对象,

        2.实例化CNContactFetchRequest对象

        3.发起通讯录信息请求,完整代码如下:

- (void)fetchAllContactsInfor {
    CNContactStore *store = [[CNContactStore alloc] init];
    CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey, CNContactPostalAddressesKey]];
    [store enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
        //后续操作
    }];
}

        这里需要注意的是通讯录请求是个异步耗时操作,建议使用异步多线程去处理。

4.获取通讯录中的群组

        我们使用 CNContactStore 类的 groupsMatchingPredicate:error: 方法来获取通讯录中的所有群组。该方法返回符合指定条件的通讯录群组数组。下面是一个获取通讯录群组的示例代码:

- (void)fetchAllGroupsCompletion:(void (^)(NSArray<CNGroup *> * _Nullable groups, NSError * _Nullable error))completion {
    CNContactStore *store = [[CNContactStore alloc] init];
    [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (!granted) {
            NSError *accessError = [NSError errorWithDomain:@"com.yourdomain.ContactManager" code:1 userInfo:@{NSLocalizedDescriptionKey: @"Access to contacts not granted"}];
            if (completion) {
                completion(nil, accessError);
            }
            return;
        }
        
        NSError *fetchError = nil;
        NSArray<CNGroup *> *groups = [store groupsMatchingPredicate:nil error:&fetchError];
        if (fetchError) {
            if (completion) {
                completion(nil, fetchError);
            }
        } else {
            if (completion) {
                completion(groups, nil);
            }
        }
    }];
}

5.操作联系人

1.增加联系人

        要在iOS中增加一个联系人信息,可以使用 CNMutableContact 类来创建一个可变的联系人对象,然后通过 CNContactStore 类的 executeSaveRequest:error: 方法将其保存到通讯录中。以下是一个示例代码:

- (void)addContactWithName:(NSString *)name phoneNumber:(NSString *)phoneNumber {
    // 创建一个可变的联系人对象
    CNMutableContact *contact = [[CNMutableContact alloc] init];
    
    // 设置联系人的姓名
    contact.givenName = name;
    
    // 创建一个电话号码对象,并添加到联系人的电话号码数组中
    CNLabeledValue *phoneNumberValue = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMobile value:[CNPhoneNumber phoneNumberWithStringValue:phoneNumber]];
    contact.phoneNumbers = @[phoneNumberValue];
    
    // 创建联系人存储请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
    [saveRequest addContact:contact toContainerWithIdentifier:nil]; // 使用默认的通讯录容器
    
    // 获取联系人存储对象
    CNContactStore *store = [[CNContactStore alloc] init];
    
    // 将联系人存储请求提交给通讯录
    NSError *error = nil;
    if (![store executeSaveRequest:saveRequest error:&error]) {
        NSLog(@"Error adding contact: %@", error.localizedDescription);
    } else {
        NSLog(@"Contact added successfully!");
    }
}

2.更新联系人信息

        要在iOS中更新联系人信息,可以使用 CNMutableContact 类创建一个可变的联系人对象,并将其修改后保存到通讯录中。以下是一个示例代码:

- (void)updateContactWithIdentifier:(NSString *)identifier withName:(NSString *)name phoneNumber:(NSString *)phoneNumber {
    // 获取联系人对象
    CNContactStore *store = [[CNContactStore alloc] init];
    NSError *error = nil;
    CNContact *contact = [store unifiedContactWithIdentifier:identifier keysToFetch:@[CNContactGivenNameKey, CNContactPhoneNumbersKey] error:&error];
    if (error) {
        NSLog(@"Error fetching contact: %@", error.localizedDescription);
        return;
    }
    
    // 创建一个可变的联系人对象,并复制原始联系人的属性
    CNMutableContact *mutableContact = [contact mutableCopy];
    
    // 更新联系人的姓名和电话号码
    mutableContact.givenName = name;
    CNPhoneNumber *newPhoneNumber = [CNPhoneNumber phoneNumberWithStringValue:phoneNumber];
    CNLabeledValue *phoneNumberValue = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMobile value:newPhoneNumber];
    mutableContact.phoneNumbers = @[phoneNumberValue];
    
    // 创建联系人存储请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
    [saveRequest updateContact:mutableContact];
    
    // 提交联系人存储请求给通讯录
    if (![store executeSaveRequest:saveRequest error:&error]) {
        NSLog(@"Error updating contact: %@", error.localizedDescription);
    } else {
        NSLog(@"Contact updated successfully!");
    }
}

        在这个示例中,我们首先通过联系人的唯一标识符获取到原始的 CNContact 对象。然后,我们创建一个可变的 CNMutableContact 对象,并使用原始联系人的属性对其进行初始化。接下来,我们更新了联系人的姓名和电话号码。最后,我们创建了一个 CNSaveRequest 对象,并通过 updateContact: 方法将修改后的联系人对象添加到保存请求中。最终,我们使用 CNContactStore 对象的 executeSaveRequest:error: 方法来执行保存请求。

3.删除联系人信息

        要在iOS中删除联系人信息,可以使用 CNMutableContact 类创建一个可变的联系人对象,并将其标记为已删除,然后保存到通讯录中。以下是一个示例代码:

- (void)deleteContactWithIdentifier:(NSString *)identifier {
    // 获取联系人对象
    CNContactStore *store = [[CNContactStore alloc] init];
    NSError *error = nil;
    CNContact *contact = [store unifiedContactWithIdentifier:identifier keysToFetch:@[] error:&error];
    if (error) {
        NSLog(@"Error fetching contact: %@", error.localizedDescription);
        return;
    }
    
    // 创建一个可变的联系人对象,并将其标记为已删除
    CNMutableContact *mutableContact = [contact mutableCopy];
    mutableContact.contactType = CNContactTypePerson;
    
    // 创建联系人存储请求
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
    [saveRequest deleteContact:mutableContact];
    
    // 提交联系人存储请求给通讯录
    if (![store executeSaveRequest:saveRequest error:&error]) {
        NSLog(@"Error deleting contact: %@", error.localizedDescription);
    } else {
        NSLog(@"Contact deleted successfully!");
    }
}

        在这个示例中,我们首先通过联系人的唯一标识符获取到原始的 CNContact 对象。然后,我们创建一个可变的 CNMutableContact 对象,并使用原始联系人的属性对其进行初始化。接下来,我们将可变联系人对象的 contactType 属性设置为 CNContactTypePerson,这将将联系人标记为普通个人联系人。最后,我们创建了一个 CNSaveRequest 对象,并通过 deleteContact: 方法将标记为已删除的联系人对象添加到保存请求中。最终,我们使用 CNContactStore 对象的 executeSaveRequest:error: 方法来执行保存请求。

6.监听通讯录变化

        要在iOS应用中监听通讯录的变化,可以使用 CNContactStoreDidChangeNotification 通知。

8.参考文章

1.Apple官方文档

2.权限配置

05-04 08:42