iOS 全新的联系人与联系人UI框架
Demo地址:我的github仓库
啦啦啦,一天一更新博客的节奏啊,前天晚上研究滴滴出行APP,发现它有一个紧急联系人的功能诶!!!
宝宝仔细的研究了一下,发现弹出联系人的控制器(CNContactPickerViewController)之后当选择一个联系人之后,
滴滴上就出现了我选择的那个联系人的名字诶!!!
跟我存储联系人的名字一模一样!!!
由此进行了一番研究,于昨晚在浩如烟海的博客中找到了这篇比较详细的博客与大家分享,其中做了一些修改。
一、引言
在以前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对象:
CNMutableContact * contact = [[CNMutableContact alloc]init];
设置联系人头像:
contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"Icon.png"]);
设置联系人姓名:
//设置名字contact.givenName = @"Yanhua";//设置姓氏contact.familyName = @"Wong";
设置联系人邮箱:
CNLabeledValue *homeEmail = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:@"emywong@sina.com"];CNLabeledValue *workEmail =[CNLabeledValue labeledValueWithLabel:CNLabelWork value:@"wangyanhua@d*****y.com.cn"];contact.emailAddresses = @[homeEmail,workEmail];
这里需要注意,emailAddresses属性是一个数组,数组中是才CNLabeledValue对象,CNLabeledValue对象主要用于创建一些联系人属性的键值对应,通过这些对应,系统会帮我们进行数据的格式化,例如CNLabelHome,就会将号码格式成家庭邮箱的格式,相应的其他键如下:
//家庭
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);
设置联系人电话:
contact.phoneNumbers = @[[CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberiPhone value:[CNPhoneNumber phoneNumberWithStringValue:@"***********"]]];
联系人电话的配置方式和邮箱类似,键值如下:
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中的一个新的类,专门用来创建电话号码,之中方法如下:
@interface CNPhoneNumber : NSObject <NSCopying, NSSecureCoding>//通过类方法创建
+ (instancetype)phoneNumberWithStringValue:(NSString *)stringValue;
//通过初始化方法创建
- (instancetype)initWithStringValue:(NSString *)string;@property (readonly, copy, NS_NONATOMIC_IOSONLY) NSString *stringValue;@end
设置联系人地址:
CNMutablePostalAddress * homeAdress = [[CNMutablePostalAddress alloc]init];homeAdress.street = @"某街道";homeAdress.city = @"威海市";homeAdress.state = @"山东省"; homeAdress.country = @"中国"; homeAdress.postalCode = @"221B";contact.postalAddresses = @[[CNLabeledValue labeledValueWithLabel:CNLabelHome value:homeAdress]];
设置生日:
NSDateComponents * birthday = [[NSDateComponents alloc]init];birthday.day=5;birthday.month=2;birthday.year=1995;contact.birthday=birthday;
2、创建添加联系人请求:CNSaveRequest
CNSaveRequest是用于存储联系人的请求类,通过这个类,我们可以创建批量添加、修改或者删除联系人的请求,例如添加上面我们创建的联系人对象:
//初始化方法CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];//添加联系人[saveRequest addContact:contact toContainerWithIdentifier:nil];
这个类中还有许多方便我们操作的方法:
@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是一个用于存取联系人的上下文桥梁,现在,把我们创建的添加联系人的请求写入:
CNContactStore * store = [[CNContactStore alloc]init];[store executeSaveRequest:saveRequest error:nil];
在模拟器上运行程序,打开联系人,效果如下:
联系人界面:
联系人详情:
三、获取格式化的联系人信息
iOS9中,ContactFramework也为开发者提供了非常方便的格式化信息的方法,还拿我们上面创建的联系人对象举例:
1、获取格式化的联系人姓名
NSString * foematter =[CNContactFormatter stringFromContact:contact style:CNContactFormatterStyleFullName];NSLog(@"%@",foematter);
这个运行后会打印出jaki zhang,其中style风格枚举如下:
typedef NS_ENUM(NSInteger, CNContactFormatterStyle)
{//获取全名CNContactFormatterStyleFullName,//获取拼音全名CNContactFormatterStylePhoneticFullName,
} NS_ENUM_AVAILABLE(10_11, 9_0);
2、获取格式化的联系人地址
NSString * foematter =[CNPostalAddressFormatter stringFromPostalAddress:homeAdress style:CNPostalAddressFormatterStyleMailingAddress];NSLog(@"%@",foematter);
打印如下:
四、提取联系人
在开发中,提取联系人的使用率要远远高于创建联系人,ContactFramework提取联系人的方式,类似于数据库的检索方式,通过配置条件,提取出我们需要的数据,例如:
CNContactStore * stroe = [[CNContactStore alloc]init];//检索条件,检索所有名字中有WO的联系人NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"wong"];//提取数据NSArray * contacts = [stroe unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
keysToFetch是设置提取联系人的哪些数据,如上则只提取出检索联系人的名字。
同样,也可以通过请求的方式来对联系人进行遍历:
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
示例如下:
弹出联系人列表:
CNContactPickerViewController * con = [[CNContactPickerViewController alloc]init];[self presentViewController:con animated:YES completion:nil];
效果如下:
联系人逻辑的相关处理主要在CNContactPickerDelegate中完成:
//视图取消时 调用的方法
- (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则是用来显示具体联系人的详细信息的,比如:
CNContactViewController * con = [CNContactViewController viewControllerForContact:contact];[self presentViewController:con animated:YES completion:nil];
相关代理回调函数如下:
//将要展示联系人信息与已经展示联系人信息的回调
- (BOOL)contactViewController:(CNContactViewController *)viewController shouldPerformDefaultActionForContactProperty:(CNContactProperty *)property;
- (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(nullable CNContact *)contact;
iOS 全新的联系人与联系人UI框架相关推荐
- iOS微信QQ聊天界面的UI框架以及Socket简单实现群聊功能
7.1日更新 Python3 TCP Demo相关 https://blog.csdn.net/Deft_MKJing/article/details/80851879 2.2日更新,socket简易 ...
- iOS之UI--主流框架的搭建-- 仿制QQ的UI框架
iOS之UI--主流框架的搭建-- 仿制QQ的UI框架 使用XCode搭建多个控制器界面,一般在实际开发中建议超过四个控制器界面使用纯代码. 下面的实例其实已经超过了四个,总结详细步骤的目的,主要是更 ...
- WWDC19 苹果宣布全新 UI 框架 SwiftUI
2019 年 WWDC 大会上,苹果在压轴环节向大众宣布了基于 Swift 语言构建的全新 UI 框架 -- SwiftUI.开发者可通过它快速为所有的 Apple 平台创建美观.动态的应用程序. 在 ...
- iOS 9人机界面指南(一):UI设计基础
[ISUX译]iOS 9人机界面指南(一):UI设计基础 raina2015.10.29 文章索引 1.1 为iOS而设计(Designing for iOS) 1.1.1 设计跟随内容 (Defer ...
- Android 开源UI框架汇总
1. github排名 https://github.com/trending,github搜索:https://github.com/search 2.https://github.com/wasa ...
- iOS 9人机界面指南(四):UI元素
iOS 9人机界面指南(四):UI元素 2016-02-14 11:51 编辑: suiling 分类:产品设计 来源:腾讯ISUX 0 31 iOS 9人机界面指南苹果文档 java高级软件 ...
- Google跨平台UI框架 Flutter beta 重磅发布,这里有你需要了解的一切
2018年2月27日,在西班牙巴塞罗那世界移动大会上,Google发布 Flutter 的第一个 beta 版本.Flutter 是 Google 用以帮助开发者在 iOS 和 Android 两个平 ...
- vue和哪个php框架搭配,vue配什么ui框架比较好
Vue是一种用于构建用户界面的渐进式框架,它可以与各种框架或工具结合使用,如果是做PC端应用,选择ElementUI框架最好,做App移动端开发选择AUI或ionIc框架最好. Vue介绍: Vue是 ...
- dotnet Multi-platform App UI 多平台应用 UI 框架简介
现在可以使用 .NET 构建一切应用.富有生产力的 .NET 是当前数百万的开发者选择这个平台的理由.在 .NET 5 微软统一了整个 .NET 平台,将 .NET Core 和 Mono 以及基于 ...
最新文章
- Python函数的非固定参数
- bagging and boosting
- python笔记之while和for循环练习
- KAFKA分布式消息系统
- 11-图像梯度-Sobel算子
- 计算机技术在工程施工中的应用,浅析计算机技术及网络在工程施工中的应用
- 【转】其实Unix很简单
- CentOS7通过定时脚本阻断异常IP连接SSH(实测)
- 数据库索引如何工作? [关闭]
- 《人月神话》读书笔记2--空间技能
- 如何在前端删除项目中的文件_如何在macOS上恢复已删除的文件
- 安卓4.2系统_五分钟了解 海贝(HiBy)R6PRO 安卓智能Hi-Fi播放器
- 车牌识别算法_向滥用远光灯说不,易泊车牌识别算法了解一下?
- 计算机基础雨课堂答案,基于“雨课堂”助推大学计算机基础课革新
- 使用python读写xlsx格式中的数据【xlrd、pywin32】
- m基于BP神经网络的障碍物避障和路线规划matlab仿真
- SequoiaDB 巨杉数据库-隔离级别
- 用python判断身份证号性别_验证身份证号的Python脚本
- 【Bluetooth蓝牙开发】九、BLE协议之GATT
- ubuntu不能检测到扩展副屏或双屏,不能使用键盘功能键,tweaks扩展动画消失的可能原因与可能的解决办法
热门文章
- oracle几种字符类型总结
- Project 2013 理论基础
- AI文案通过图灵测试!一秒生成2万条广告神器问世
- BIT琪露诺的完美算法教室 3.初上征途的za
- 【游戏开发创新】Unity 2D图片任意形状破碎碎裂效果,以此纪念我的牙光荣牺牲
- SAS——列联表(复习3)
- java基础学不会,转:《学不会的JAVA,消不了的忧愁》之四-JSP教程,Java基础
- 2018.12.10 第4题:定义两个类,描述如下: [必做题] 4.1定义一个人类Person: 4.1.1定义一个方法sayHello(),可以向对方发出问候语“hello,my name is
- 构造代码块、静态代码块、无参构造函数和有参构造函数的执行顺序
- 广告牌定时器怎么设置时间_定时开关怎么调整时间?