iOS获取通讯录的方法

目录

前言

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类型的枚举,定义如下:

typedef NS_ENUM(NSInteger, CNAuthorizationStatus){

CNAuthorizationStatusNotDetermined = 0,//用户未决定是否授权访问

CNAuthorizationStatusRestricted,//授权受限制

CNAuthorizationStatusDenied,//拒绝授权

CNAuthorizationStatusAuthorized//已经授权

} NS_ENUM_AVAILABLE(10_11, 9_0);

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

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

objectivec 复制代码
- (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对象,

CNContactStore *store = [[CNContactStore alloc] init];

2.实例化CNContactFetchRequest对象

CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]];

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

objectivec 复制代码
- (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: 方法来获取通讯录中的所有群组。该方法返回符合指定条件的通讯录群组数组。下面是一个获取通讯录群组的示例代码:

objectivec 复制代码
- (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: 方法将其保存到通讯录中。以下是一个示例代码:

objectivec 复制代码
- (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 类创建一个可变的联系人对象,并将其修改后保存到通讯录中。以下是一个示例代码:

objectivec 复制代码
- (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 类创建一个可变的联系人对象,并将其标记为已删除,然后保存到通讯录中。以下是一个示例代码:

objectivec 复制代码
- (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.权限配置

相关推荐
四谎真好看3 分钟前
Java 黑马程序员学习笔记(进阶篇19)
java·笔记·学习·学习笔记
新子y1 小时前
【小白笔记】最大交换 (Maximum Swap)问题
笔记·python
你要飞5 小时前
Hexo + Butterfly 博客添加 Live2D 看板娘指南
笔记
ajsbxi8 小时前
【Java 基础】核心知识点梳理
java·开发语言·笔记
RollingPin8 小时前
iOS八股文之 RunLoop
ios·多线程·卡顿·ios面试·runloop·ios保活·ios八股文
呱呱巨基8 小时前
vim编辑器
linux·笔记·学习·编辑器·vim
新子y9 小时前
【小白笔记】普通二叉树(General Binary Tree)和二叉搜索树的最近公共祖先(LCA)
开发语言·笔记·python
聪明的笨猪猪9 小时前
Java JVM “调优” 面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
爱学习的uu9 小时前
CURSOR最新使用指南及使用思路
人工智能·笔记·python·软件工程
YuCaiH9 小时前
Linux文件处理
linux·笔记·嵌入式