1、在iOS9.0之后,系统的通讯录改成了Contacts/Contacts.h,虽然之前的AddressBook/AddressBook.h框架还可以用,由于在新的框架中采用的都是面向对象的思想,所有苹果建议使用新的框架来做通讯录相关操作。下面简单介绍一下Contacts/Contacts.h框架添加,获取联系人。
2、首先导入头文件,头文件中包含了很多操作通讯录以及联系人的头文件,大家可以去看一下,
#import <Contacts/Contacts.h>
3、在iOS9.0之后的通讯录相关操作,同样需要授权通讯录,其授权的操作和iOS9之前的授权模式大致相同,只不过,需要创建来获取通讯录,
// CNAuthorizationStatusNotDetermined = 0,
// CNAuthorizationStatusRestricted,
// CNAuthorizationStatusDenied,
// CNAuthorizationStatusAuthorized
// 获取授权状态
// [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
// ios 9
CNContactStore *contactStore = [[CNContactStore alloc] init]; // 创建通讯录
// 请求授权
[contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@"授权成功!");
// [self creatContact]; // 添加联系人
[self getAllContact]; // 获取所有联系人
} else {
NSLog(@"授权失败!");
}
}];
如果授权成功,就可以获取联系人等操作,如果授权失败,可能就需要根据需求温馨的提示一下用户了。
4、添加联系人
添加联系人需要创建联系人对象,在Contacts/Contacts.h框架中,联系人对象有2个类,一个是CNMutableContact(可变的联系人对象,对象中的属性是可以赋值的),CNContact(不可变的联系人对象,对象中的属性只能是可读的,在拿到联系人数据之后,可以用这个类对象展示数据),所有添加联系人就只能用CNMutableContact了,
#pragma mark - 添加联系人
- (void)creatContact{
CNMutableContact *contact = [[CNMutableContact alloc] init]; // 第一次运行的时候,会获取通讯录的授权(对通讯录进行操作,有权限设置)
// 1、添加姓名(姓+名)
contact.givenName = @"san";
contact.familyName = @"wangg";
// contact.nickname = @"hahahah"; // 昵称
// contact.nameSuffix = @"nameSuffix"; // 名字后缀
// contact.namePrefix = @"namePrefix"; // 前字后缀
// contact.previousFamilyName = @"previousFamilyName"; // 之前的familyName
// 2、添加职位相关
contact.organizationName = @"公司名称";
contact.departmentName = @"开发部门";
contact.jobTitle = @"工程师";
// 3、这一部分内容会显示在联系人名字的下面,phoneticFamilyName属性设置的话,会影响联系人列表界面的排序
// contact.phoneticGivenName = @"GivenName";
// contact.phoneticFamilyName = @"FamilyName";
// contact.phoneticMiddleName = @"MiddleName";
// 4、备注
contact.note = @"同事";
// 5、头像
contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"1"]);
// 6、添加生日
NSDateComponents *birthday = [[NSDateComponents alloc] init];
birthday.year = 1990;
birthday.month = 6;
birthday.day = 6;
contact.birthday = birthday;
// 7、添加邮箱
CNLabeledValue *homeEmail = [CNLabeledValue labeledValueWithLabel:CNLabelEmailiCloud value:@"[email protected]"];
// CNLabeledValue *workEmail = [CNLabeledValue labeledValueWithLabel:CNLabelWork value:@"11111888888"];
// CNLabeledValue *iCloudEmail = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:@"34454554"];
// CNLabeledValue *otherEmail = [CNLabeledValue labeledValueWithLabel:CNLabelOther value:@"6565448"];
contact.emailAddresses = @[homeEmail];
// 8、添加电话
CNLabeledValue *homePhone = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberiPhone value:[CNPhoneNumber phoneNumberWithStringValue:@"11122233344"]];
contact.phoneNumbers = @[homePhone];
// 9、添加urlAddresses,
CNLabeledValue *homeurl = [CNLabeledValue labeledValueWithLabel:CNLabelURLAddressHomePage value:@"http://baidu.com"];
contact.urlAddresses = @[homeurl];
// 10、添加邮政地址
CNMutablePostalAddress *postal = [[CNMutablePostalAddress alloc] init];
postal.city = @"北京";
postal.country = @"中国";
CNLabeledValue *homePostal = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:postal];
contact.postalAddresses = @[homePostal];
// 获取通讯录操作请求对象
CNSaveRequest *request = [[CNSaveRequest alloc] init];
[request addContact:contact toContainerWithIdentifier:nil]; // 添加联系人操作(同一个联系人可以重复添加)
// 获取通讯录
CNContactStore *store = [[CNContactStore alloc] init];
// 保存联系人
[store executeSaveRequest:request error:nil]; // 通讯录有变化之后,还可以监听是否改变(CNContactStoreDidChangeNotification)
}
创建联系人的操作基本上就是以上那么多,也有可以表述的不对,但基本的用法就是这样了,
在保存联系人的时候是用的CNSaveRequest对象,然后调用通讯录的- (BOOL)executeSaveRequest:(CNSaveRequest *)saveRequest error:(NSError *__nullable *__nullable)error __WATCHOS_PROHIBITED;方法,这个方法返回的是一个bool值,如果添加成功的话,返回YES,否则返回NO,所以可以根据返回的值进行判断是逗保存成功。
5、有关CNSaveRequest类
这个类是用来操作联系人动作的(添加,修改,删除等等),通讯录中的联系人的操作都是通过这个来完成的,其中的方法如下,
// 往通讯录中添加联系人
- (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;
一般我们用到的就是添加联系人。
6、获取联系人
获取联系人有多种方法,这里介绍2中
(1)利用通讯录的一个获取统一联系人的方法获取所有联系人数组,数组中装的都是contact对象;其中的一些过滤操作已经在代码中解释,
// 创建通讯录
CNContactStore *contactStore = [[CNContactStore alloc] init];
NSError *error;
NSPredicate *predicate = [CNContact predicateForContactsMatchingName:@"wangg"]; // 按照谓词进行查询,predicate必须利用CNContact的predicate分类创建,方法都在<Contacts/CNContact+Predicates.h>中
NSArray *keys = @[CNContactEmailAddressesKey,CNContactFamilyNameKey,CNContactGivenNameKey]; // 所查询的联系人中的信息按照keys中的字断进行提取
NSArray *allContacts = [contactStore unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error]; // allContacts数组中存储查询的联系人
NSLog(@"count==%lu",(unsigned long)allContacts.count);
for (CNContact *contact in allContacts) {
NSLog(@"==%@",contact);
}
(2)指定搜索条件获取联系人,根据查询条件,然后利用通讯录遍历所有的联系人,
// 创建通讯录
CNContactStore *contactStore = [[CNContactStore alloc] init];
NSError *error;
// 创建联系人请求对象
NSArray *fetchArr = @[CNContactGivenNameKey,CNContactFamilyNameKey,CNContactEmailAddressesKey]; // 所查询的联系人中的信息按照keys中的字断进行提取
CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:fetchArr];
// fetchRequest.predicate = nil;
fetchRequest.predicate = [CNContact predicateForContactsMatchingName:@"li"]; // 设定匹配条件
// 指定搜索条件获取联系人 ,如果fetchRequest.predicate = nil,查询所有的联系人
[contactStore enumerateContactsWithFetchRequest:fetchRequest error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
NSLog(@"%@",contact);
}];
7、联系人的删除,修改操作
在我获取到联系人的信息的时候,试图拿到所获取的联系人,然后进行修改,但是由于拿到的数据都是CNContact对象,既不能修改信息,我试图将其转换成CNMutableContact类,但是转换不了,但是如果要修改信息,首先必须从通讯录中获取数据(都是CNContact类)才能对已经存在的联系人进行修改,但是有转换不过来,试了试先创建一个CNMutableContact对象,将CNContact对象的属性都赋值过去,然后保存CNMutableContact对象,删除CNContact对象,发现保存成功,删除失败,直接再对CNMutableContact对象修改信息然后保存,竟然保存失败,这个很头疼,所以希望会的同学也帮我解决一下。