在以往的ios开发中,开发者需要获取用户的通讯录信息的时候,往往要使用AddressBook.frame框架,该框架是纯C语言的API,在开发过程中,还需要开发者手动的管理内存,这对于新进开发者很难理解和掌握。到了IOS9,苹果推出了具有OC语言的API,即Contacts框架,该框架理解简单、易于使用。联系人信息可以短时间获取、创建和修改,而且还不需要去关系对象的释放。

下面我们介绍一下Contacts框架:

在ios8以后,苹果更加注重用户的隐私,因此需要访问用户通讯录的时候,必须给用户发送授权请求,得到用户的确认后,才能进行下一步的操作。如果用户不同意,用户禁止APP获取其通讯录信息,那么这个决定必须被APP采纳,且绝对不能与用户的通讯录信息交互。不仅如此,用户随时可以在设置中更改对APP的授权,因此在任何操作的时候,都需要检查用户的授权状态。

     //1 判断是否授权成功
    if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusAuthorized) return;//授权成功直接返回
    //2 创建通讯录
    CNContactStore *store = [[CNContactStore alloc] init];
    //3授权
    [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            NSLog(@"授权成功");
        }else{
            NSLog(@"授权失败");
        }
    }];

authorizationStatusForEntityType:methods这个方法是CNContactStore的类方法,需要一个 CNEntityType 参数,返回值是授权得到的状态CNAuthorizationStatus,一共有四种,分别为:

  1. NotDetermined:表示用户还没有允许或禁止访问通讯录数据库。首次安装的应用软件处于这种状态。
  2. Restricted:不仅应用软件无法访问通讯录数据,就连用户也无法通过设置修改授权状态。该状态是由于其他限制,也就是家长控制(parental control)所导致。
  3. Denied:表示用户不允许访问通讯录数据。只有用户才能够修改该状态。
  4. Authorized:这是每个应用软件期望得到的状态。在该状态下,应用软件可以随意访问通讯录数据库,使用通讯录数据执行操作。

我们其实只需要判断授权状态是否为 CNAuthorizationStatusAuthorized 即可,如果是表示授权状态成功,否则失败,不允许访问通讯录。

CNContactStore (相当于ABAddressBook)类以编程方式展示了联系人数据库,并且提供了许多实现不同任务的方法,例如获取,保存或者更新记录,权限检查和权限请求,很多很多。

CNContact类(相当于ABRecordRef)展示一个单独的联系人记录,但是记住这个类的特性是不可变的。如果你想创建一个新的联系人记录或者更新一个已存在的联系人记录,你必须使用CNMutableContact类。

需要注意的是在于Contacts框架打交道的时候,特别是获取联系人信息时,你应该始终在后台线程中运行这些任务。因为如果一个联系人信息获取任务花去了太多时间而且在主线程运行,那么你的应用有可能无响应,然后最终导致非常糟糕的交互体验。

于此同时在导入联系人信息到APP时,很少用到所有的联系人的属性信息。在所有的Contacts 框架要搜索的数据源中获取所有联系人数据的操作,被证明是一个非常耗资源的进程,所以应该避免检索所以联系人的属性信息,而是只检索需要的一部分属性信息,这个是在Contacts框架提供了的。例如,你可以只是请求名或姓,电话等,这样可以通过排除不需要的那些数据来节约很多资源。

查询联系人代码示例:

 /** 查看联系人 */
- (void)readContact {
    if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] != CNAuthorizationStatusAuthorized) return;//授权失败直接返回     //创建通讯录对象
    CNContactStore *store = [[CNContactStore alloc] init]; // 创建获取通信录的请求对象
//拿到所有打算获取的属性对应的key(这里仅仅指定需要获取的数据,节约资源)
//我们这里仅仅作为示例,所以获取了所有的信息数据
    NSArray *typeArray = @[CNContactGivenNameKey,CNContactFamilyNameKey,CNContactPhoneNumbersKey,CNContactEmailAddressesKey,CNContactBirthdayKey,CNContactDepartmentNameKey];
    
//创建CNContactFetchRequest对象
    CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:typeArray];     //遍历所有的联系人
    [store enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) { //名字
        NSString *firstName = contact.givenName;
//姓氏
        NSString *lastName = contact.familyName;
        
        NSLog(@"%@ -- %@", firstName, lastName);
      
//获取电话信息 
        NSArray *phones = contact.phoneNumbers;
        for (int i = ; i<phones.count; i++) {             CNLabeledValue *phone = phones[i]; //获取电话号码的KEY
            NSString *label = phone.label; //获取电话号码
            CNPhoneNumber *phoneNum = phone.value;
NSString *num = phoneNum.stringValue;
            NSLog(@"name= %@ -- num = %@", label, num);
        } 
    }]; }

插入联系人示例:

 /**
 *  添加联系人
 */
- (IBAction)addContact {
    
    //1、联系人对象:CNContact
    
    //这个对象是用来配置联系人信息的,有可变的CNMutaleContact和CNContact,区别用来读取和创建联系人。CNContact对象中有许多属性,对应联系人的一些信息。
    
    //首先,创建CNMutableContact对象:
    CNMutableContact *contact = [[CNMutableContact alloc]init];
    
    //设置联系人数据
    [self setupContact:contact];
    
    
    //2、创建添加联系人请求:CNSaveRequest
    //CNSaveRequest是用于存储联系人的请求类,通过这个类,我们可以创建批量添加、修改或者删除联系人的请求,例如添加上面我们创建的联系人对象:
    
    //初始化方法
    CNSaveRequest * saveRequest = [[CNSaveRequest alloc] init];
    //添加联系人
    [saveRequest addContact:contact toContainerWithIdentifier:nil];
    
    //3 进行联系人的写入操作:CNContactStore
    //CNContactStore是一个用于存取联系人的上下文桥梁,现在,把我们创建的添加联系人的请求写入:
    CNContactStore * store = [[CNContactStore alloc]init];
    [store executeSaveRequest:saveRequest error:nil];
} /** 设置联系人信息 */
- (void)setupContact:(CNMutableContact *)contact{
    //设置联系人头像:
    contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"tour"]);
    
    //设置联系人姓名:
    //设置名字
    contact.givenName = @"xiao";
    //设置姓氏
    contact.familyName = @"zhang";
    
    //设置联系人邮箱(这里需要注意,emailAddresses属性是一个数组,数组中是才CNLabeledValue对象)
    CNLabeledValue *homeEmail = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:@"3242523553@qq.com"];
    CNLabeledValue *workEmail =[CNLabeledValue labeledValueWithLabel:CNLabelWork value:@"324266653@qq.com"];
    contact.emailAddresses = @[homeEmail,workEmail];
    
    //设置联系人电话(和邮箱类似)
    CNLabeledValue *mianPhone = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMain value:[CNPhoneNumber phoneNumberWithStringValue:@""]];
    CNLabeledValue *homePhone = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberHomeFax value:[CNPhoneNumber phoneNumberWithStringValue:@""]];
    contact.phoneNumbers = @[mianPhone, homePhone];
    
    //设置联系人地址
    CNMutablePostalAddress * homeAdress = [[CNMutablePostalAddress alloc]init];
    homeAdress.street = @"大雁塔";
    homeAdress.city = @"西安";
  homeAdress.state = @"中国";
    homeAdress.postalCode = @"xxxxx";
    contact.postalAddresses = @[[CNLabeledValue labeledValueWithLabel:CNLabelHome value:homeAdress]];
    
    //设置联系人生日
  NSDateComponents * birthday = [[NSDateComponents  alloc] init];
  birthday.day=;
    birthday.month=;
    birthday.year=;
    contact.birthday=birthday;
}

ContactsUI.frame框架

 //打开通讯录
- (IBAction)openContact {
//初始化ContactPickerViewController
    CNContactPickerViewController *pickVc = [[CNContactPickerViewController alloc] init];
    //成为自己的代理
    pickVc.delegate = self;
    //跳转控制器
    [self presentViewController:pickVc animated:YES completion:nil];
} #pragma mark - CNContactPickerDelegate
// 点击cancle按钮时候就会调用
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker{
    NSLog(@"%s", __func__);
    [picker dismissViewControllerAnimated:YES completion:nil];
} // 选中某一个联系人就会调用
//注意:只要实现了这个方法, 就不会进行下一步操作(进入详情), iOS9的做法是默认返回NO
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{
    NSLog(@"%s", __func__);
    //姓氏
    NSString *firstName = contact.familyName;
//名字
    NSString *lastName = contact.givenName;
    NSLog(@"%@---%@", firstName, lastName);
    //电话信息
    NSArray *phones = contact.phoneNumbers;
    for (CNLabeledValue *phone in phones) {
//电话名称
        NSString *name = phone.label;
//电话号码详情
        CNPhoneNumber *phoneNum = phone.value;
        NSLog(@"name = %@, phoneNum = %@", name, phoneNum.stringValue);
    }
    
} // 选中某一个联系人的某一个属性时就会调用
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty{
    NSLog(@"%s", __func__);
}

ios9-通讯录的更多相关文章

  1. 通讯录--(iOS9独有的方法)

    导入库文件   #import <ContactsUI/ContactsUI.h> #pragma mark iOS9 新出的点击通讯录的获取信息的办法 #pragma mark - 先弹 ...

  2. 获取通讯录的信息(关于iOS9.0之后新的框架-ContactFramework)

    转载自:http://my.oschina.net/u/2340880/blog/511995?p={{totalPage}} 一.引言 在以前iOS开发中,涉及联系人相关的编程,代码都非常繁琐,并且 ...

  3. iOS中通讯录的开发

    通讯录开发主要是获取用户手机中的联系人,进而可以在应用中添加好友 一 .如何访问通讯录 (1)在iOS9之前,有两个框架可以访问用户的通讯录 AddressBookUI.framework: 提供了联 ...

  4. iOS通讯录整合,兼容iOS789写法,附demo

    苹果的通讯录功能在iOS7,iOS8,iOS9 都有着一定的不同,iOS7和8用的是 <AddressBookUI/AddressBookUI.h> ,但是两个系统版本的代理方法有一些变化 ...

  5. iOS开发——高级篇——通讯录

    一.简介 1.如何访问用户的通讯录1)在iOS9之前有2个框架可以访问用户的通讯录AddressBookUI.framework提供了联系人列表界面.联系人详情界面.添加联系人界面等一般用于选择联系人 ...

  6. iOS8通讯录之联系人增删查,多号码增删操作

    #import <AddressBook/AddressBook.h> #pragma mark 删除一个号码 - (void)deleteLocalMarkSuccess:(void(^ ...

  7. ios开发 通讯录

    一.通信录开发 通信录开发主要是获取用户手机中的联系人 通过获取用户的通信录,可以在应用中添加好友等 二.如何访问用户的通讯录 在iOS9之前,有2个框架可以访问用户的通讯录 目前需要适配iOS8,所 ...

  8. IOS9中联系人对象的使用及增删改查操作的函数封装

    之前克服重重困难把IOS9中新的类联系人搞明白了,现在把增删改查封装成了函数,如下: // // ViewController.m // IOS9中联系人CNContact的使用 // // Crea ...

  9. iOS7,iOS8和iOS9的区别

    iOS7,iOS8和iOS9的区别:iOS7.0 1.iOS 7是iOS面世以来在用户界面上做出改变最大的一个操作系统.iOS 7抛弃了以往的拟物化设计,而采用了扁平化设计. 苹果在重新思考 iOS ...

  10. iOS开发学习-类似微信聊天消息中的电话号码点击保存到通讯录中的功能

    类似微信聊天消息中的电话号码点击保存到通讯录中的功能,ABAddress的实现在iOS9中是不能正常使用的,点击完成后,手机会非常的卡,iOS9之后需要使用Contact新提供的方法来实现该功能.快捷 ...

随机推荐

  1. BZOJ AC800纪念

    貌似没什么好纪念的...QAQQQ 好不容易水到了800还是记录一下好了....不过感觉水这么多题没有意义啊[思考熊] 然后就没有然后了恩 不过我到底是为什么才努力的呢...前途一阵迷茫,根本没有什么 ...

  2. 【转】js插件zClip实现复制到剪贴板功能

    相信这个功能大家平时上网经常能碰到,以前也没怎么留意怎么实现的,直到项目中需要. 网上一搜一大堆,单纯使用js方法也不是没有,但是由于各浏览器的安全机制不同,不是跨浏览器的.去看了几个常用的网站,都是 ...

  3. git clone带用户名和密码的方式

    git clone http://username:password@127.0.0.1/res/res.git

  4. iocp 小例子

    2016-08-3116:44:09 server 端 /******************************************************************* aut ...

  5. ASCII、UNICODE、UTF-8等关系

    参考如下: 网址1:http://blog.csdn.net/lx697/article/details/5914417 网址2:http://www.php100.com/html/it/bianc ...

  6. 【FPGA】【代码】资源优化,结构优化

    资源优化 原始资源 定义时初始化和复位电路初始化都起作用,删除定义的初值后 将always块描述的组合逻辑变为时序逻辑后

  7. [转载]Three Trending Computer Vision Research Areas, 从CVPR看接下来几年的CV的发展趋势

    As I walked through the large poster-filled hall at CVPR 2013, I asked myself, “Quo vadis Computer V ...

  8. ScrollView can host only one direct child

    Android 采用ScrollView布局时出现异常:ScrollView can host only one direct child. 异常原因: 主要是ScrollView内部只能有一个子元素 ...

  9. C++小项目:directx11图形程序(五):shadersclass

    这个类是用来创建着色器并设置输入布局的. 这个类比较特殊,它创建的着色器与Effect文件有关,effect文件是用高级着色语言(hlsl)编写的. shadersclass.h #pragma on ...

  10. 人工智能交互集成在线语音合成能力的Tips

    在线语音合成就是在联网的场景下将文字转换成声音,实现机器向人的声音交互.这个概念应该是比较好理解的,下面就结合官网的Android在线合成的Demo讲解一下合成的流程以及大家经常遇到的一些问题. 到官 ...