IOS开发中使用CNContact\CNMutableContact 对通讯录增删改查
IOS开发中使用CNContact\CNMutableContact 对通讯录增删改查
首先当然是把CNcontact包含在工程中:
@import Contacts;
1、下面是增加联系人的程序段:
CNMutableContact * contact = [[CNMutableContact alloc]init];
contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@""]);
//设置名字
contact.givenName = @"三强";
//设置姓氏
contact.familyName = @"钱";
CNLabeledValue *homeEmail = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:@"316045346@qq.com"];
CNLabeledValue *workEmail =[CNLabeledValue labeledValueWithLabel:CNLabelWork value:@"316045346@qq.com"];
contact.emailAddresses = @[homeEmail,workEmail];
//家庭
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:@""]]];
CNMutablePostalAddress * homeAdress = [[CNMutablePostalAddress alloc]init];
homeAdress.street = @"贝克街";
homeAdress.city = @"伦敦";
homeAdress.state = @"英国";
homeAdress.postalCode = @"221B";
contact.postalAddresses = @[[CNLabeledValue labeledValueWithLabel:CNLabelHome value:homeAdress]];
NSDateComponents * birthday = [[NSDateComponents alloc]init];
birthday.day=;
birthday.month=;
birthday.year=;
contact.birthday=birthday; // //初始化方法
CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
// 添加联系人(可以)
[saveRequest addContact:contact toContainerWithIdentifier:nil];
// 写入
CNContactStore * store = [[CNContactStore alloc]init];
[store executeSaveRequest:saveRequest error:nil];
2、下面是删除联系人的程序段,在苹果的开发文档中是这么描述的:
其中的contact参数是要被删除的联系人,也就以为这这个也就意味着这个联系人之前在通讯录存在,也就是说它不是我们新建的一个联系人对象,而是从通讯录中查出来的一个联系人对象,所以我们先要去查找联系人,这样的话先创建一个谓词,然后去查找,找到之后再执行删除,以下是程序段:
// CNContactStore * store = [[CNContactStore alloc]init];
// //检索条件,检索所有名字中GivenName是W的联系人
// NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"W"];
// //提取数据
// NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
// CNMutableContact *contact1 = [contacts objectAtIndex:0];
//
//
//// //初始化方法
// CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
//
// //删除联系人(不行)
// [saveRequest deleteContact:contact1];
3、关于更新联系人,在这里纠结了好久以下是整个过程,希望大家少走弯路:
1)、看到苹果的官方文档里,对这个updateContact方法轻描淡写,我也就没有注意,想想只要先把需要的联系人读出来,然后修改属性,并使用updateContact方法更新就行,然后我编写了以下程序(有问题的程序,灰色底色标注):
CNContactStore * store = [[CNContactStore alloc]init];
//检索条件,检索所有名字中有zhang的联系人
NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"张"];
//提取数据
NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
CNMutableContact *contact1 = [contacts objectAtIndex:];
// 修改联系人的属性
contact1.givenName = @"heh";
// 实例化一个CNSaveRequest
CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
[saveRequest updateContact:contact1];
但是以上程序段运行的时候总会提示错误,并且crash掉,错误提示是:
-[CNContact setGivenName:]: unrecognized selector sent to instance 0x7fd5ba755660
然后Add一个Expection Breakpoint,程序总是运行到修改联系人属性这句卡住,见下图:
然后就很纠结啊,上网查找原因,在QQ群里问大神,得到的答案是对象被提前释放了,然后我也有这个感觉,我打断点调试,发现当运行CNMutableContact *contact1 = [contacts objectAtIndex:0];这句之后,contact1就变成了CNContact类型的对象,不再是CNMutableContact。而苹果官方文档要求要更新或者添加一个联系人到通讯录,首先要求这个对象是可变的,也就是只有CNMutableContact类型的才能修改对象的属性并更新通讯录,而且要求要更新的联系人在通讯录中必须存在。于是我去苹果的官方手册里继续查找原因,然而并没找到如何读取一个联系人并读成可变类型的联系人的方法,我就继续翻翻,找各种可能性,后来被我看到一段代码:
let mutableContact = contact.mutableCopy() as! CNMutableContact
let newEmail = CNLabeledValue(label: CNLabelHome, value: "john@example.com")
mutableContact.emailAddresses.append(newEmail) let saveRequest = CNSaveRequest()
saveRequest.updateContact(mutableContact)
try! store.executeSaveRequest(saveRequest)
这段代码是swift语言写的,我先注意到第六行是saveRequest.updateContact,也就是说用了更新的语句,那么它更新的对象是什么类型呢?看看第一句就明白了,虽然我不懂swift,但看得出大概的意思是深拷贝(mutableCopy)了一个对象,那我也深拷贝一个呗,接下来我写了以下代码:
CNContactStore * store = [[CNContactStore alloc]init];
//检索条件,检索所有名字中有zhang的联系人
NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"张"];
//提取数据
NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
CNContact*contact1 = [contacts objectAtIndex:];
CNMutableContact *contact2 = [contact1 mutableCopy];
// 修改联系人的属性
contact2.givenName = @"asdfasdfas";
// 实例化一个CNSaveRequest
CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
[saveRequest updateContact:contact2];
满怀希望的运行,发现并没有修改我的联系人,接下来继续找问题,修改成以下代码:
CNContactStore * store = [[CNContactStore alloc]init];
//检索条件,检索所有名字中有zhang的联系人
NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"张"];
//提取数据
NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
CNMutableContact *contact2 = [[contacts objectAtIndex:] mutableCopy];
// 修改联系人的属性
contact2.givenName = @"asdfasdfas";
// 实例化一个CNSaveRequest
CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
[saveRequest updateContact:contact2];
还是不行,继续去找苹果的茬,再读读上面发现的那段代码:
let mutableContact = contact.mutableCopy() as! CNMutableContact
let newEmail = CNLabeledValue(label: CNLabelHome, value: "john@example.com")
mutableContact.emailAddresses.append(newEmail) let saveRequest = CNSaveRequest()
saveRequest.updateContact(mutableContact)
try! store.executeSaveRequest(saveRequest)
发现第七句,我这儿没有用,想起使用addContact方法新增联系人到通讯录的时候最后要用这句,那就加上这句吧:
CNContactStore * store = [[CNContactStore alloc]init];
//检索条件,检索所有名字中有zhang的联系人
NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"张"];
//提取数据
NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
CNMutableContact *contact2 = [[contacts objectAtIndex:] mutableCopy];
// 修改联系人的属性
contact2.givenName = @"asdfasdfas";
// 实例化一个CNSaveRequest
CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
[saveRequest updateContact:contact2];
[store executeSaveRequest:saveRequest error:nil];
再次运行,并打到模拟器的通讯录,惊喜的发现姓张的联系人变成名字变成了asdfasdfas,见下图:
这就是结果,在看看我是在哪儿找到苹果的官方文档里面的那段代码的出处:
IOS开发中使用CNContact\CNMutableContact 对通讯录增删改查的更多相关文章
- iOS开发——数据持久化OC篇&plist文件增删改查操作
Plist文件增删查改 主要操作: 1.//获得plist路径 -(NSString*)getPlistPath: 2.//判断沙盒中名为plistname的文件是否存在 -(BOOL ...
- IOS9中联系人对象的使用及增删改查操作的函数封装
之前克服重重困难把IOS9中新的类联系人搞明白了,现在把增删改查封装成了函数,如下: // // ViewController.m // IOS9中联系人CNContact的使用 // // Crea ...
- iOS云存储:CloudKit 基本使用教程 增删改查(Swift)
一.从iOS8开始,苹果为开发者提供了ClouKit,可以把我们的应用程序和用户数据存储在iCloud上,用于代替后台服务器,开发移动代码即可. 二.设置 (1)需要一个开发者账号,并且设置一个bun ...
- 一个在ASP.NET中利用服务器控件GridView实现数据增删改查的例子
备注:这是我辅导的一个项目开发组的一个例子,用文章的方式分享出来,给更多的朋友参考.其实我们这几年的项目中,都不怎么使用服务器控件的形式了,而是更多的采用MVC这种开发模式.但是,如果项目的历史背景是 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查
上一篇文章(https://www.cnblogs.com/meowv/p/12913676.html)我们用Code-First的方式创建了博客所需的实体类,生成了数据库表,完成了对EF Core的 ...
- mongodb windows的安装方法和添加到任务管理器中、检测是否成功、增删改查命令
转: mongodb安装方法: https://blog.csdn.net/heshushun/article/details/77776706 mongodb检测安装成功 .以及增删改 ...
- Ado.net中简单的DBHelper类(增删改查)
private static string connString = "server=.;database=hotel;uid=aa;pwd=123";//最好从配置文件中取出 p ...
- Python中列表、元组、字典增删改查基本区别
1.定义: 列表:num = ["a","b"."c"] ##定义后可增删改查 元组:num = ("a"," ...
- django中数据库的配置及相关增删改查
ORM ORM是什么?:(在django中,根据代码中的类自动生成数据库的表也叫--code first) ORM:Object Relational Mapping(关系对象映射) 类名对应---- ...
随机推荐
- cocos2d-x-2.2.6创建工程
1.下载并安装Python,我的版本是2.7.3,不要太高,据说不能用.2.配置环境变量,将Python的安装的根目录加入系统环境变量的Path路径中(不赘述,自行配置)3.配置好之后打开cmd命令行 ...
- Mac linux 安装memcached服务 用法
今天在Mac上安装memcached服务的时候 由于安装memcached之前需要安装libevent依赖包 所以使用brew install libevent 安装过程中报错 Warning: Yo ...
- Codeforces Round #272 (Div. 1) B 构造 math
http://www.codeforces.com/contest/477/problem/C 题目大意:给你n个集合,每个集合里面有四个数字,他们的gcd是k,输出符合条件的集合中m,m为集合中最大 ...
- STM32软件复位(基于库文件V3.5)
源:STM32软件复位(基于库文件V3.5) void SoftReset(void) { __set_FAULTMASK(); // 关闭所有中端 NVIC_SystemReset();// 复位 ...
- C# 经典入门12章-使用泛型类型-2
- Ubuntu系统如何修改主机名
1.执行命令 hostname temp_name 这样主机名就改掉了.只不过重启后名字会恢复不一定使我们想要的.机器重启后会重新去读取/etc/hostname里面存储的主机名.所以如果想永久改掉的 ...
- Android复习--广播
广播有两种方式,一种静态广播,一种动态广播. 静态广播-->静态广播接收器在配置文件里面注册. 动态广播-->而动态广播接收器在代码里面注册. 广播的发送: Context.sendBro ...
- HDU 4421 ZOJ 3656 Bit Magic
2-SAT,不要所有位置全部建好边再判断,那样会MLE的. 正解是,每一位建好边,就进行一次2-SAT. #include<cstdio> #include<cstring> ...
- Intellij idea生成Hibernate实体类
反向生成基于注解的Hibernate实体类 1. 为项目添加Hibernate支持 2. 在IDE右边找到database,然后按照步骤添加数据. 3. 保存后.在主面板左侧有persistence, ...
- 深究Xcode的bitcode设置
深究Xcode的bitcode设置 转发至:http://www.jianshu.com/p/f42a33f5eb61 前言 做iOS开发的朋友们都知道,目前最新的Xcode7,新建项目默认就打开了b ...