转载自:http://my.oschina.net/u/2340880/blog/511995?p={{totalPage}}

一、引言

在以前iOS开发中,涉及联系人相关的编程,代码都非常繁琐,并且框架的设计也不是Objective-C风格的,这使开发者用起来非常的难受。在iOS9中,apple终于解决了这个问题,全新的Contacts Framework将完全替代AddressBookFramework,AddressBookFramework也将成为历史被弃用。至于AddressBookFramework的相关api如何繁琐,在以前的博客中有记录,地址如下:

联系人信息相关编程:http://my.oschina.net/u/2340880/blog/407347

联系人UI界面相关编程:http://my.oschina.net/u/2340880/blog/407973

这一新的框架是iOS9新特性中十分受欢迎的一个。apple的Objective—C体系也更加完善与强大。

二、让我们来添加一个联系人

新的框架的整体思路是通过配置与请求来管理联系人,这样做有一个非常大的好处,逻辑简单,代码层次清晰。如下,通过添加一个联系人来向大家做演示:

1、联系人对象:CNContact

这个对象是用来配置联系人信息的,有可变的CNMutaleContact和CNContact,区别用来读取和创建联系人。CNContact对象中有许多属性,对应联系人的一些信息。

首先,创建CNMutableContact对象:

1
 CNMutableContact * contact = [[CNMutableContact alloc]init];

设置联系人头像:

1
contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"Icon-114.png"]);

设置联系人姓名:

1
2
3
4
    //设置名字
    contact.givenName = @"jaki";
    //设置姓氏
    contact.familyName = @"zhang";

设置联系人邮箱:

1
2
3
     CNLabeledValue *homeEmail = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:@"316045346@qq.com"];
     CNLabeledValue *workEmail =[CNLabeledValue labeledValueWithLabel:CNLabelWork value:@"316045346@qq.com"];
     contact.emailAddresses = @[homeEmail,workEmail];

这里需要注意,emailAddresses属性是一个数组,数组中是才CNLabeledValue对象,CNLabeledValue对象主要用于创建一些联系人属性的键值对应,通过这些对应,系统会帮我们进行数据的格式化,例如CNLabelHome,就会将号码格式成家庭邮箱的格式,相应的其他键如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//家庭
CONTACTS_EXTERN NSString * const CNLabelHome                             NS_AVAILABLE(10_11, 9_0);
//工作
CONTACTS_EXTERN NSString * const CNLabelWork                             NS_AVAILABLE(10_11, 9_0);
//其他
CONTACTS_EXTERN NSString * const CNLabelOther                            NS_AVAILABLE(10_11, 9_0);
 
// 邮箱地址
CONTACTS_EXTERN NSString * const CNLabelEmailiCloud                      NS_AVAILABLE(10_11, 9_0);
 
// url地址
CONTACTS_EXTERN NSString * const CNLabelURLAddressHomePage               NS_AVAILABLE(10_11, 9_0);
 
// 日期
CONTACTS_EXTERN NSString * const CNLabelDateAnniversary                  NS_AVAILABLE(10_11, 9_0);

设置联系人电话:

1
contact.phoneNumbers = @[[CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberiPhone value:[CNPhoneNumber phoneNumberWithStringValue:@"12344312321"]]];

联系人电话的配置方式和邮箱类似,键值如下:

1
2
3
4
5
6
7
CONTACTS_EXTERN NSString * const CNLabelPhoneNumberiPhone                NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelPhoneNumberMobile                NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelPhoneNumberMain                  NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelPhoneNumberHomeFax               NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelPhoneNumberWorkFax               NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelPhoneNumberOtherFax              NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelPhoneNumberPager                 NS_AVAILABLE(10_11, 9_0);

这里的CNPhoneNumber对象也是iOS9中的一个新的类,专门用来创建电话号码,之中方法如下:

1
2
3
4
5
6
7
8
9
10
@interface CNPhoneNumber : NSObject <NSCopying, NSSecureCoding>
 
//通过类方法创建
+ (instancetype)phoneNumberWithStringValue:(NSString *)stringValue;
//通过初始化方法创建
- (instancetype)initWithStringValue:(NSString *)string;
 
@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *stringValue;
 
@end

设置联系人地址:

1
2
3
4
5
6
  CNMutablePostalAddress * homeAdress = [[CNMutablePostalAddress alloc]init];
    homeAdress.street = @"贝克街";
    homeAdress.city = @"伦敦";
    homeAdress.state = @"英国";
    homeAdress.postalCode = @"221B";
    contact.postalAddresses = @[[CNLabeledValue labeledValueWithLabel:CNLabelHome value:homeAdress]];

设置生日:

1
2
3
4
5
NSDateComponents * birthday = [[NSDateComponents  alloc]init];
    birthday.day=7;
    birthday.month=5;
    birthday.year=1992;
    contact.birthday=birthday;

2、创建添加联系人请求:CNSaveRequest

CNSaveRequest是用于存储联系人的请求类,通过这个类,我们可以创建批量添加、修改或者删除联系人的请求,例如添加上面我们创建的联系人对象:

1
2
3
4
   //初始化方法
    CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
    //添加联系人
    [saveRequest addContact:contact toContainerWithIdentifier:nil];

这个类中还有许多方便我们操作的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@interface CNSaveRequest : NSObject
//添加一个联系人
- (void)addContact:(CNMutableContact *)contact toContainerWithIdentifier:(nullable NSString *)identifier;
 
//更新一个联系人
- (void)updateContact:(CNMutableContact *)contact;
//删除一个联系人
- (void)deleteContact:(CNMutableContact *)contact;
//添加一组联系人
- (void)addGroup:(CNMutableGroup *)group toContainerWithIdentifier:(nullable NSString *)identifier;
//更新一组联系人
- (void)updateGroup:(CNMutableGroup *)group;
//删除一组联系人
- (void)deleteGroup:(CNMutableGroup *)group;
//向组中添加子组
- (void)addSubgroup:(CNGroup *)subgroup toGroup:(CNGroup *)group NS_AVAILABLE(10_11, NA);
//在组中删除子组
- (void)removeSubgroup:(CNGroup *)subgroup fromGroup:(CNGroup *)group NS_AVAILABLE(10_11, NA);
//向组中添加成员
- (void)addMember:(CNContact *)contact toGroup:(CNGroup *)group;
//向组中移除成员
- (void)removeMember:(CNContact *)contact fromGroup:(CNGroup *)group;
 
@end

3、进行联系人的写入操作:CNContactStore

CNContactStore是一个用于存取联系人的上下文桥梁,现在,把我们创建的添加联系人的请求写入:

1
2
    CNContactStore * store = [[CNContactStore alloc]init];
    [store executeSaveRequest:saveRequest error:nil];

在模拟器上运行程序,打开联系人,效果如下:

联系人界面:

联系人详情:

三、获取格式化的联系人信息

iOS9中,ContactFramework也为开发者提供了非常方便的格式化信息的方法,还拿我们上面创建的联系人对象举例:

1、获取格式化的联系人姓名

1
2
    NSString * foematter =[CNContactFormatter stringFromContact:contact style:CNContactFormatterStyleFullName];
    NSLog(@"%@",foematter);

这个运行后会打印出jaki zhang,其中style风格枚举如下:

1
2
3
4
5
6
7
typedef NS_ENUM(NSInteger, CNContactFormatterStyle)
{
    //获取全名
    CNContactFormatterStyleFullName,
   //获取拼音全名
    CNContactFormatterStylePhoneticFullName,
} NS_ENUM_AVAILABLE(10_11, 9_0);

2、获取格式化的联系人地址

1
2
    NSString * foematter =[CNPostalAddressFormatter stringFromPostalAddress:homeAdress style:CNPostalAddressFormatterStyleMailingAddress];
    NSLog(@"%@",foematter);

打印如下:

四、提取联系人

在开发中,提取联系人的使用率要远远高于创建联系人,ContactFramework提取联系人的方式,类似于数据库的检索方式,通过配置条件,提取出我们需要的数据,例如:

1
2
3
4
5
    CNContactStore * stroe = [[CNContactStore alloc]init];
    //检索条件,检索所有名字中有zhang的联系人
    NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"zhang"];
    //提取数据
    NSArray * contacts = [stroe unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];

keysToFetch是设置提取联系人的哪些数据,如上则只提取出检索联系人的名字。

同样,也可以通过请求的方式来对联系人进行遍历:

1
2
3
4
5
    CNContactStore * stroe = [[CNContactStore alloc]init];
    CNContactFetchRequest * request = [[CNContactFetchRequest alloc]initWithKeysToFetch:@[CNContactPhoneticFamilyNameKey]];
    [stroe enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
        NSLog(@"%@",contact);
    }];

五、ContactFramework UI相关

iOS9中,系统也为我们封装好了一套联系人的UI界面,用起来也十分方便,主要新增的controller有两个:

CNContactPickerViewController:展示联系人列表的controller

CNContactViewController:展示联系人详细信息的controller

示例如下:

弹出联系人列表:

1
2
    CNContactPickerViewController * con = [[CNContactPickerViewController alloc]init];
    [self presentViewController:con animated:YES completion:nil];

效果如下:

联系人逻辑的相关处理主要在CNContactPickerDelegate中完成:

1
2
3
4
5
6
7
//视图取消时 调用的方法
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker;
//选中与取消选中时调用的方法
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact;
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray<CNContact*> *)contacts;
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperties:(NSArray<CNContactProperty*> *)contactProperties;

CNContactViewController则是用来显示具体联系人的详细信息的,比如:

1
2
    CNContactViewController * con = [CNContactViewController viewControllerForContact:contact];
    [self presentViewController:con animated:YES completion:nil];

相关代理回调函数如下:

1
2
3
//将要展示联系人信息与已经展示联系人信息的回调
- (BOOL)contactViewController:(CNContactViewController *)viewController shouldPerformDefaultActionForContactProperty:(CNContactProperty *)property;
- (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(nullable CNContact *)contact;

获取通讯录的信息(关于iOS9.0之后新的框架-ContactFramework)的更多相关文章

  1. IOS 获取通讯录中信息

    获取通讯录中信息 一. 我们设置一个ABAddressBookRef类型的属性addressBook. 二. 要获得通讯录中的信息,我们需要获取访问通讯录的权限. 在运行下面的获取权限的方法的时候,系 ...

  2. Android软件开发之获取通讯录联系人信息

    Android手机的通讯录联系人全部都存在系统的数据库中,如果须要获得通讯里联系人的信息就须要访问系统的数据库,才能将信息拿出来. 这一篇文章我主要带领同学们熟悉Android的通讯录机制. 图中选中 ...

  3. ios 获取通讯录的所有信息

    iOS获取通讯录全部信息 ABAddressBookRef addressBook = ABAddressBookCreate(); CFArrayRef results = ABAddressBoo ...

  4. iOS获取通讯录所有联系人信息

    以下是2种方式: 第一种方法: GetAddressBook.h #import <Foundation/Foundation.h> @interface GetAddressBook : ...

  5. android6.0获取通讯录权限

    android6.0中,获取通讯录的权限是    <uses-permission android:name="android.permission.GET_ACCOUNTS" ...

  6. iOS6.0下获取通讯录用户列表

    自iOS6.0后获取通讯录列表需要询问用户,经过用户同意后才可以获取通讯录用户列表.而且ABAddressBookRef的初始化工作也由ABAddressBookCreate函数转变为ABAddres ...

  7. Magicodes.WeiChat——使用OAuth 2.0获取微信用户信息

    使用Magicodes.WeiChat,可以很方便的获取到微信用户的信息.在使用OAuth 2.0之前,你先需要做以下操作: 1)在开发者中心修改[网页授权获取用户基本信息],在弹出的界面输入自己的根 ...

  8. React Native之获取通讯录信息并实现类通讯录列表(ios android)

    React Native之获取通讯录信息并实现类通讯录列表(ios android) 一,需求分析 1,获取通讯录信息,筛选出通讯录里有多少好友在使用某个应用. 2,获取通讯录信息,实现类通讯录,可拨 ...

  9. iOS获取通讯录 电话号码与姓名

    // 还是导入 #import <AddressBook/AddressBook.h> - (void)fetchAddressBookBeforeIOS9{ ABAddressBookR ...

随机推荐

  1. Storm系列(十六)架构分析之Executor-Bolt

    准备消息循环的数据 函数原型: 1  let[executor-sampler (mk-stats-sampler (:storm-conf executor-data))] 主要功能: 定义tupl ...

  2. 动态规划:最长上升子序列(LIS)

    转载请注明原文地址:http://www.cnblogs.com/GodA/p/5180560.html 学习动态规划问题(DP问题)中,其中有一个知识点叫最长上升子序列(longest  incre ...

  3. Python模块导入及使用经验回顾 [ 持续更新 ]

    1,若需要导入的模块并不是一个简单的*.py文件,而是在Lib目录下的一个文件夹,则要注意检查这个文件夹下有无__init__.py文件(该文件虽然经常为空,但是缺失该文件,对模块的导入有很大的影响) ...

  4. Microsoft Dynamics CRM 2011 面向Internet部署 (IFD) ADFS虚拟机环境搭建的步骤(CRM与ADFS装在同一台服务器上) 摘自网络

    1: 安装windows server 2008 R2 中文版 (过程略) 安装完成后设置机器名和IP地址, 本过程机器名 crm5dev,192.168.0.110 dns: 192.168.0.1 ...

  5. List使用Foreach 修改集合时,会报错的解决方案 (Error: Collection was modified; enumeration operation may not execute. ) - 摘自网络

    当用foreach遍历Collection时,如果对Collection有Add或者Remove操作时,会发生以下运行时错误: "Collection was modified; enume ...

  6. ios中的容器类 ViewController

    https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/AboutViewContro ...

  7. poj 3281 Dining【拆点网络流】

    Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11828   Accepted: 5437 Descripti ...

  8. XML模式:Dublin Core

    Dublin Core 标准是一种信息分类方法,常用于图书馆.Dublin Core 标准有一个 XML Schema 定义了如何使用 XML 描述这类信息.Dublin Core 可以有效地对各种信 ...

  9. visual studio 2015提示IE10未安装

    将以下代码写入文本: @ECHO OFF :IE10HACK REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer&q ...

  10. IMP 导入数据报错 OCI-21500 OCI-22275

    IMP导入数据报错如下: OCI-21500: internal error code, arguments: [kgepop: no error frame to pop to], [], [], ...