本文主要是介绍iOS开发------获取系统联系人(Contacts篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Contacts.framework是Apple在 iOS9.0 替代AddressBook.framework的框架,至于AddressBook是做什么的框架,楼主默认看到博文的开发者是知道的 O(∩_∩)O。
如果想了解AddressBook的使用欢迎查看一下楼主之前关于AddressBook的博文,本篇不做过多的缀余:
iOS开发——获取系统联系人(AddressBook篇)
iOS开发——操作通讯录(AddressBook篇)&通讯录UI(AddressBookUI篇)
每次iOS发布新的版本(甚至每年的WWDC大会举行完毕)很多敏锐的开发者都准备或者对新版本特性进行适配。当然这些大神肯定会在iOS9发布后在第一时间对通讯录功能进行适配,一些稍微不太敏锐的开发者鉴于AddressBook在iOS9下初次提醒以及讨厌适配的繁琐,也就不以为然。
但随着iOS10的发布,那么适配相关框架就显得格外重要(不是说AddressBook不能使用了,但为了项目的健壮性以及良好的体验性,还是非常建议第一时间适配的。当然,这句话不仅限于Contacts部分)。
如果大家的项目还需要适配iOS8(当然,大多数公司肯定是也不会抛弃iOS7的用户),那么使用AddressBook是必然的;但如果在iOS9+的系统上,楼主还是非常建议使用最新的Contacts.framework框架的.
个人推荐的主要是下面两点原因(来源于楼主查看官方文档,编写Demo以及使用instruments的体会):
AddressBook与其他相关废弃框架相似一样 (ex:ALAsset-图片库),语言风格更接近于C语言(当然也可以说就是C语言),不在ARC管理之下(对于习惯使用ARC下的开发者算是不小的挑战),使用不太便利并容易造成内存泄露。
新的框架无论在查看开发文档、使用、读取速度还是灵活性都远好于废弃框架,内存泄露易于查找以及补漏。
这里还是要分享一下源码,楼主整合AddressBook.framework以及Contacts.framework的DEMO
预览图
左边为AddressBook框架进行的演示,右边为Contact框架进行的演示.
根据不同的版本进行自动适配,如果是iOS9,自动使用Contact.framework.
权限描述
在iOS10上由于权限有很多的坑,本博文的内容需要使用通讯录权限.
那么不要忘记在项目的info.plist文件中加入如下描述:Privacy - Contacts Usage Description
,描述字符串:RITL want to use your Contacts(这个随意)
,尽可能的写点东西吧,听说如果不写上线可能会被Apple拒绝..
获取权限-CNContactStore
负责获得权限、请求权限以及执行操作请求的类就是CNContactStore
,具体Demo中的代码如下:
/**检测权限并作响应的操作*/
- (void)__checkAuthorizationStatus
{//这里有一个枚举类:CNEntityType,不过没关系,只有一个值:CNEntityTypeContactsswitch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]){//存在权限case CNAuthorizationStatusAuthorized://获取通讯录[self __obtainContacts:self.completeBlock];break;//权限未知case CNAuthorizationStatusNotDetermined://请求权限[self __requestAuthorizationStatus];break;//如果没有权限case CNAuthorizationStatusRestricted:case CNAuthorizationStatusDenied://需要提示self.defendBlock();break;}
}
请求联系人列表-CNContactStore
这里有几种比较常用的思路
1.使用自带的枚举方法一次性获得所有的属性
// 使用枚举方法对所有的联系人对象(CNContact)进行列出,该方法是同步的
- (BOOL)enumerateContactsWithFetchRequest:(CNContactFetchRequest *)fetchRequesterror:(NSError *__nullable *__nullable)errorusingBlock:(void (^)(CNContact *contact, BOOL *stop))block;
2.先获取所有联系人的identifier,再根据identifier读取联系人信息(Demo中使用的该思路)
// 通过identifer获得一个唯一的CNContact
- (nullable CNContact *)unifiedContactWithIdentifier:(NSString *)identifierkeysToFetch:(NSArray<id<CNKeyDescriptor>> *)keyserror:(NSError *__nullable *__nullable)error;
遍历请求类-CNContactFetchRequest
感觉这里介绍一下CNContactFetchRequest
类还是有必要的,毕竟当初在这里也是浪费了点时间,它是一个遍历请求的类,我们可以通过初始化该类的实例对象,告诉contactStore我们需要遍历contact的某些属性:
//实例化CNContactFetchRequest对象,通过一个遍历键的描述数组
- (instancetype)initWithKeysToFetch:(NSArray <id<CNKeyDescriptor>>*)keysToFetch NS_DESIGNATED_INITIALIZER;
键值描述协议-CNKeyDescriptor
如果我们单纯的进入开发文档,我们会发现他是一个空协议,刚开始看到这里的时候楼主表示很蒙B
//没有任何的required和optional方法
@protocol CNKeyDescriptor <NSObject, NSSecureCoding, NSCopying>
@end
但很快就发现了下面这个Category
// //Allows contact property keys to be used with keysToFetch.
// 允许contact的属性键作为遍历的键
@interface NSString (Contacts) <CNKeyDescriptor>
@end
如果还是有点疑惑,那么相信看到下面就不会再有困惑了呢。没错,可以直接将下列字符串当成CNKeyDescriptor对象写入数组
//标识符
CONTACTS_EXTERN NSString * const CNContactIdentifierKey NS_AVAILABLE(10_11, 9
这篇关于iOS开发------获取系统联系人(Contacts篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!