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如下:

- (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.发起通讯录信息请求,完整代码如下:

- (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.权限配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/5115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ABAP 数据写入Excel 并保存

参考老白 https://www.cnblogs.com/liaojunbo/archive/2011/09/06/2168552.html 但是缺zcl_excel 。需要从 dotabap要引入abap2xlsx 英文版进入后 尝试了一下 1&#xff09;列的宽度自适应么有找到在哪里&#xff1f; 列宽设置 lo_worksheet->set_column_width( ip_co…

企微社群群发消息:强化社群互动与营销新策略

在数字化营销日益盛行的今天&#xff0c;企业微信社群已成为企业与用户之间沟通互动的重要桥梁。而企微社群群发消息功能&#xff0c;更是这一桥梁上的重要纽带&#xff0c;它能够帮助企业高效、精准地传递信息&#xff0c;强化社群互动&#xff0c;提升营销效果。本文将详细介…

C++ //练习 13.40 为你的StrVec类添加一个构造函数,它接受一个Initializer_list<string>参数。

C Primer&#xff08;第5版&#xff09; 练习 13.40 练习 13.40 为你的StrVec类添加一个构造函数&#xff0c;它接受一个Initializer_list参数。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /****************************…

微软的access数据库使用

“小规模数据用Excel&#xff0c;大规模数据用Access。” 当涉及到大规模数据时&#xff0c;使用excel非常的卡顿&#xff0c;使用access就不会出现这个问题。 一、常用操作 1.新建一个数据库 直接右键&#xff0c;新建 access数据库 2.excel内容导入到access中&#xff08;成…

【Web UI自动化】Python+Selenium 环境配置

安装Python 官网地址&#xff1a;https://www.python.org/&#xff0c;Downloads菜单下选择适合自己的系统版本&#xff0c;我的是Windows。 点击进入以后&#xff0c;可以看到当前最新版本。 点击上面的链接&#xff0c;页面下滑&#xff0c;找到下载链接&#xff0c;根据…

天冕科技亮相第十七届深圳国际金融博览会!

第十七届深圳国际金融博览会在深圳会展中心正式开幕&#xff0c;天冕科技跟随南山区组团集体亮相&#xff0c;充分展现金融活力。此次金博会&#xff0c;南山区政府共遴选了包括天冕科技在内的三家优秀金融科技企业组团参展&#xff0c;以特色与创新的案例展示了辖区金融业发展…

【简单讲解下FastStone Capture】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

python部署linux

项目做完了&#xff0c;就涉及到了部署 部署 Python的打包部署方式有多种&#xff0c;具体取决于项目的需求、规模以及所使用的工具。以下是几种常见的Python打包部署方式&#xff1a; 使用pip安装&#xff1a;对于小型的Python库或工具&#xff0c;通常可以直接通过pip进行安…

idea添加scala库,src\main\scala‘ is duplicated in module ‘XXX‘.

环境&#xff1a; jdk 17 scala 2.11.8 IntelliJ IDEA 2023.1.1 (Ultimate Edition) Windows 10 专业版 22H2 报错解释&#xff1a; 这个错误表明在IntelliJ IDEA中的Scala模块&#xff08;名为XXX&#xff09;配置中存在重复的目录。具体来说&#xff0c;src\main\scala目…

目标检测应用场景—数据集【NO.33】血细胞图像分类和检测数据集

写在前面&#xff1a;数据集对应应用场景&#xff0c;不同的应用场景有不同的检测难点以及对应改进方法&#xff0c;本系列整理汇总领域内的数据集&#xff0c;方便大家下载数据集&#xff0c;若无法下载可关注后私信领取。关注免费领取整理好的数据集资料&#xff01;今天分享…

类加载器和双亲委派机制体会及分析和arthas使用

类加载器的分类 验证流程使用arthas arthas下载地址 Releases alibaba/arthas (github.com) 使用过程 想要被arthas识别到 需要让应用程序不退出 System.in.read(); 随便运行一个类 public class HshbDemo {public static final int a 1;public static void main(String…

头歌:RDD的创建 -Scala

第1关&#xff1a;集合并行化创建RDD 任务描述 本关任务&#xff1a;计算并输出各个学生的总成绩。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.集合并行化创建RDD&#xff0c;2.reduceByKey算子、foreach算子 集合创建RDD Spark会将集合中的数据拷贝到集…

企业营销战略新思考:营销5.0与开源AI智能名片S2B2C商城小程序引领私域流量经营新纪元

随着互联网的深入发展&#xff0c;企业营销战略已经不再是单一、静态的规划&#xff0c;而是一个持续进化、与市场紧密相连的动态过程。在这个过程中&#xff0c;营销5.0和开源AI智能名片S2B2C商城小程序的结合&#xff0c;为企业营销战略注入了新的活力&#xff0c;也为私域流…

IntelliJ IDEA - Auto filling Java call arguments 插件教程

首先&#xff0c;安装该插件&#xff0c;下载完毕后重启 IDEA 当 userService 中方法需要参数的时候&#xff0c;我们一般都是自己手动写这些参数&#xff0c;是很费劲的。因此就出现了一个插件解决这类问题 Auto filling Java call arguments 光标点击需要填写参数的位置 Alt …

深入理解Java消息中间件-性能优化和调优

性能优化和调优是构建高性能系统的重要环节&#xff0c;这对于Apache Kafka这样的消息中间件尤为重要。下面我们将介绍一些具体的性能优化和调优操作方式&#xff0c;以帮助你更好地利用Kafka来构建高性能的消息系统。 合理配置Kafka集群&#xff1a;合理配置Kafka集群的节点数…

ESP32-C3第二路串口(非调试)串口打通(4)

接前一篇文章&#xff1a;ESP32-C3第二路串口&#xff08;非调试&#xff09;串口打通&#xff08;3&#xff09; 本文内容参考&#xff1a; 基于 esp-idf 的 UART 应用例程解读_uart asynchronous example with separate receive an-CSDN博客 特此致谢&#xff01; 上一回对…

2024.4.29力扣每日一题——将矩阵按对角线排序

2024.4.29 题目来源我的题解方法一 模拟 题目来源 力扣每日一题&#xff1b;题序&#xff1a;1329 我的题解 方法一 模拟 先以第一行的每个元素作为对角线的开始&#xff0c;然后再以第一列的每个元素作为对角线的开始。并在遍历过程中记录&#xff08;数组或者list&#xf…

品深茶的抗癌效果怎么样?

茶叶中的一些成分&#xff0c;如茶多酚、儿茶素等&#xff0c;具有抗氧化和抗炎作用&#xff0c;这些作用在一定程度上可以抑制癌细胞的生长和扩散。 然而&#xff0c;这些成分在茶叶中的含量和生物利用率会受到多种因素的影响&#xff0c;如茶叶的品种、制作工艺、饮茶方式等…

rk356x 关于yocto编译linux及bitbake实用方法

Yocto 完整编译 source oe-init-build-envbitbake core-image-minimalYocto 查询包名 bitbake -s | grep XXX // 获取rockchip相关包 :~/rk3568/yocto$ bitbake -s | grep rockchip android-tools-conf-rockchip :1.0-r0 gstreamer1.0-rockchip …

我开源了一款阿里云OSS的spring-boot-starter

在上一篇文章中我们介绍了如何使用SpringBoot集成阿里云oss&#xff1a; 什么&#xff01;没有Starter的阿里云OSS也能集成到SpringBoot&#xff1f; 但是这个方式还是需要自己去写配置类去配置很多的东西&#xff0c;那么我在想&#xff0c;为什么不自己写一个阿里云OSS的spri…