iOS - Contacts 通讯录
Contacts 通讯录
1、访问通讯录
设置系统访问通讯录权限

1.1 iOS 9.0 及 iOS 9.0 之后获取通讯录的方法
iOS 9.0 及 iOS 9.0 之后获取通讯录的方法
// 包含头文件
#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h> // 获取通讯录信息,自定义方法
- (void)fetchAddressBookOnIOS9AndLater { // 创建 CNContactStore 对象
CNContactStore *contactStore = [[CNContactStore alloc] init]; // 首次访问需用户授权
if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusNotDetermined) { // 首次访问通讯录 [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { if (!error){ if (granted) { // 允许 NSLog(@"已授权访问通讯录");
NSArray *contacts = [self fetchContactWithContactStore:contactStore]; // 访问通讯录 dispatch_async(dispatch_get_main_queue(), ^{ // 主线程 更新 UI
NSLog(@"contacts:%@", contacts); }); } else { // 拒绝 NSLog(@"拒绝访问通讯录");
} } else {
NSLog(@"发生错误!");
}
}]; } else { // 非首次访问通讯录 NSArray *contacts = [self fetchContactWithContactStore:contactStore]; // 访问通讯录
dispatch_async(dispatch_get_main_queue(), ^{ // 主线程 更新 UI
NSLog(@"contacts:%@", contacts); });
}
} // 访问通讯录,自定义方法
- (NSMutableArray *)fetchContactWithContactStore:(CNContactStore *)contactStore { // 判断访问权限
if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusAuthorized) { // 有权限访问
NSError *error = nil; // 创建数组,必须遵守 CNKeyDescriptor 协议,放入相应的字符串常量来获取对应的联系人信息
NSArray <id<CNKeyDescriptor>> *keysToFetch = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey]; // 获取通讯录数组
NSArray<CNContact*> *arr = [contactStore unifiedContactsMatchingPredicate:nil keysToFetch:keysToFetch error:&error]; if (!error) { NSMutableArray *contacts = [NSMutableArray array];
for (int i = 0; i < arr.count; i++) { CNContact *contact = arr[i];
NSString *givenName = contact.givenName;
NSString *familyName = contact.familyName;
NSString *phoneNumber = ((CNPhoneNumber *)(contact.phoneNumbers.lastObject.value)).stringValue; [contacts addObject:@{@"name":[givenName stringByAppendingString:familyName], @"phoneNumber":phoneNumber}];
}
return contacts; } else {
return nil;
} } else { // 无权限访问
NSLog(@"无权限访问通讯录"); return nil;
}
}
效果

1.2 iOS 9.0 之前获取通讯录的方法
iOS 9.0 之前获取通讯录的方法
// 包含头文件
#import <AddressBook/AddressBook.h> // 获取通讯录信息,自定义方法
- (void)fetchAddressBookBeforeIOS9 { ABAddressBookRef addressBook = ABAddressBookCreate(); // 首次访问需用户授权
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) { // 首次访问通讯录 ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { if (!error) { if (granted) { // 允许 NSLog(@"已授权访问通讯录");
NSArray *contacts = [self fetchContactWithAddressBook:addressBook]; dispatch_async(dispatch_get_main_queue(), ^{ // 主线程 更新 UI
NSLog(@"contacts:%@", contacts); }); } else { // 拒绝 NSLog(@"拒绝访问通讯录");
} } else {
NSLog(@"发生错误!");
}
});
} else { // 非首次访问通讯录 NSArray *contacts = [self fetchContactWithAddressBook:addressBook]; dispatch_async(dispatch_get_main_queue(), ^{ // 主线程 更新 UI
NSLog(@"contacts:%@", contacts); });
}
} // 访问通讯录,自定义方法
- (NSMutableArray *)fetchContactWithAddressBook:(ABAddressBookRef)addressBook { if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) { // 有权限访问 // 获取联系人数组
NSArray *array = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); NSMutableArray *contacts = [NSMutableArray array];
for (int i = 0; i < array.count; i++) { //获取联系人
ABRecordRef people = CFArrayGetValueAtIndex((__bridge ABRecordRef)array, i); // 获取联系人详细信息,如:姓名,电话,住址等信息
NSString *firstName = (__bridge NSString *)ABRecordCopyValue(people, kABPersonFirstNameProperty);
NSString *lastName = (__bridge NSString *)ABRecordCopyValue(people, kABPersonLastNameProperty);
ABMutableMultiValueRef *phoneNumRef = ABRecordCopyValue(people, kABPersonPhoneProperty);
NSString *phoneNumber = ((__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneNumRef)).lastObject; [contacts addObject:@{@"name": [firstName stringByAppendingString:lastName], @"phoneNumber": phoneNumber}];
}
return contacts; } else { // 无权限访问 NSLog(@"无权限访问通讯录"); return nil;
}
}
效果

2、对通讯录的操作
对通讯录的操作
// 包含头文件
#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h> // 遵守协议
<CNContactPickerDelegate> @property (nonatomic, strong) NSArray *contacts;
@property (nonatomic, strong) NSArray *groups;
2.1 打开通讯录
打开通讯录
// 初始化 CNContactPickerViewController
CNContactPickerViewController *contactPickerVC = [[CNContactPickerViewController alloc] init]; // 设置代理,需遵守 CNContactPickerDelegate 协议
contactPickerVC.delegate = self; // 显示联系人窗口视图
[self presentViewController:contactPickerVC animated:YES completion:nil]; // 取消,CNContactPickerDelegate 协议方法
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker { // 点击联系人控制器的 Cancel 按钮执行该方法,picker 联系人控制器 NSLog(@"取消");
} // 选中联系人,CNContactPickerDelegate 协议方法
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact { // 选中联系人时执行该方法,picker 联系人控制器,contact 联系人 NSLog(@"联系人的资料:%@", contact);
[self dismissViewControllerAnimated:YES completion:nil]; // 显示联系人详细页面
CNContactViewController *contactVC = [CNContactViewController viewControllerForContact:contact]; contactVC.displayedPropertyKeys = @[CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactFamilyNameKey,
CNContactInstantMessageAddressesKey, CNContactEmailAddressesKey,
CNContactDatesKey, CNContactUrlAddressesKey, CNContactBirthdayKey,
CNContactImageDataKey]; [self presentViewController:contactVC animated:YES completion:nil];
}
2.2 联系人操作
1、增加联系人
// 增加的联系人信息
CNMutableContact *contact = [self initializeContact]; // 创建请求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; // 添加联系人
[saveRequest addContact:contact toContainerWithIdentifier:nil]; // 同步到通讯录
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:NULL]; // 初始化联系人信息
- (CNMutableContact *)initializeContact { // 创建联系人对象
CNMutableContact *contact = [[CNMutableContact alloc] init]; // 设置联系人的头像
contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"demo5"]); // 设置联系人姓名
contact.givenName = @"Qian"; // 设置姓氏
contact.familyName = @"Chia"; // 设置联系人邮箱
CNLabeledValue *homeEmail = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:@"qianchia@icloud.com"];
CNLabeledValue *workEmail = [CNLabeledValue labeledValueWithLabel:CNLabelWork value:@"qianchia@icloud.com"];
CNLabeledValue *otherEmail = [CNLabeledValue labeledValueWithLabel:CNLabelOther value:@"qianchia@icloud.com"];
contact.emailAddresses = @[homeEmail,workEmail,otherEmail]; // 设置机构名
contact.organizationName = @"互联网"; // 设置部门
contact.departmentName = @"Development"; // 设置工作的名称
contact.jobTitle = @"iOS"; // 设置社会的简述
CNSocialProfile *profile = [[CNSocialProfile alloc] initWithUrlString:@"12306.cn" username:@"lily" userIdentifier:nil service:@"IT行业"];
CNLabeledValue *socialProfile = [CNLabeledValue labeledValueWithLabel:CNSocialProfileServiceGameCenter value:profile];
contact.socialProfiles = @[socialProfile]; // 设置电话号码
CNPhoneNumber *mobileNumber = [[CNPhoneNumber alloc] initWithStringValue:@"15188888888"];
CNLabeledValue *mobilePhone = [[CNLabeledValue alloc] initWithLabel:CNLabelPhoneNumberMobile value:mobileNumber];
contact.phoneNumbers = @[mobilePhone]; // 设置与联系人的关系
CNContactRelation *friend = [[CNContactRelation alloc] initWithName:@"好朋友"];
CNLabeledValue *relation = [CNLabeledValue labeledValueWithLabel:CNLabelContactRelationFriend value:friend];
contact.contactRelations = @[relation]; // 设置生日
NSDateComponents *birthday = [[NSDateComponents alloc] init];
birthday.day = 6;
birthday.month = 5;
birthday.year = 2000;
contact.birthday = birthday; return contact;
}
2、删除联系人
// 要删除的联系人
CNMutableContact *contact = [self.contacts[0] mutableCopy]; // 创建请求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; // 删除联系人
[saveRequest deleteContact:contact]; // 同步到通讯录
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:NULL];
3、修改联系人
// 要修改的联系人信息
CNMutableContact *contact = [self.contacts[0] mutableCopy];
contact.givenName = @"Qianqian"; // 创建请求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; // 修改联系人
[saveRequest updateContact:contact]; // 同步到通讯录
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:NULL];
4、查询联系人
// 要查询的联系人 GivenName
NSString *checkName = @"Qian"; // 检索条件
NSPredicate *predicate = [CNContact predicateForContactsMatchingName:checkName]; // 提取数据 (keysToFetch:@[CNContactGivenNameKey] 是设置提取联系人的哪些数据)
CNContactStore *store = [[CNContactStore alloc] init];
NSArray *contactArray = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:NULL]; self.contacts = contactArray;
2.3 联系人群组操作
1、增加群组
// 要增加的群组
CNMutableGroup *group = [[CNMutableGroup alloc] init];
group.name = @"QianFriend"; // 创建请求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; // 增加群组
[saveRequest addGroup:group toContainerWithIdentifier:nil]; // 同步到通讯录
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:NULL];
2、删除群组
// 要删除的群组
CNMutableGroup *group = self.groups[0]; // 创建请求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; // 删除群组
[saveRequest deleteGroup:group]; // 同步到通讯录
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:NULL];
3、修改群组
// 要修改的群组
CNMutableGroup *group = self.groups[0];
group.name = @"QianWork"; // 创建请求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; // 修改群组
[saveRequest updateGroup:group]; // 同步到通讯录
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:NULL];
4、查询群组
CNContactStore *store = [[CNContactStore alloc] init]; // 查询所有的 group(predicate 参数为空时会查询所有的 group)
NSArray *groupArray = [store groupsMatchingPredicate:nil error:NULL]; self.groups = groupArray;
5、向群组中添加联系人
// 要添加的联系人和群组
CNContact *contact = self.contacts[0];
CNMutableGroup *group = self.groups[0]; // 创建请求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; // 向群组中添加联系人
[saveRequest addMember:contact toGroup:group]; // 同步到通讯录
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:NULL];
6、从群组中删除联系人
// 要删除的联系人和群组
CNContact *contact = self.contacts[0];
CNMutableGroup *group = self.groups[0]; // 创建请求
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; // 从群组中删除联系人
[saveRequest removeMember:contact fromGroup:group]; // 同步到通讯录
CNContactStore *store = [[CNContactStore alloc] init];
[store executeSaveRequest:saveRequest error:NULL];
iOS - Contacts 通讯录的更多相关文章
- ios读取通讯录信息
ios读取通讯录信息 (2012-05-22 14:07:11) 标签: ios读取通讯录 it iphone如许app读取通讯录信息,读取通讯录信息时需要加载AddressBookUI 和Add ...
- The Best One iOS Contacts App
The Best One iOS Contacts App iPhone Contacts App SwiftUI Awesome iOS Contacts App 一款高度还原华为通讯录 iOS A ...
- ios 获取通讯录的所有信息
iOS获取通讯录全部信息 ABAddressBookRef addressBook = ABAddressBookCreate(); CFArrayRef results = ABAddressBoo ...
- iOS 修改通讯录联系人地址(address)崩溃原因分析
目前项目中需要对iOS系统通讯录进行读取,修改操作.在进行对地址修改的时候,出现了一个奇怪现象: ● 如果contact没有address字段(或者一个全新的contact),对它的address进行 ...
- iOS有关通讯录操作
一.首先获取用户通讯录授权信息. 在AppDelegate中导入#import <AddressBook/AddressBook.h>框架,在下列方法中获取授权信息. - (BOOL)ap ...
- iOS 获得通讯录中联系人的所有属性--b
ABAddressBookRef addressBook = ABAddressBookCreate(); CFArrayRef results = ABAddressBookCopyArrayOfA ...
- iOS获取通讯录所有联系人信息
以下是2种方式: 第一种方法: GetAddressBook.h #import <Foundation/Foundation.h> @interface GetAddressBook : ...
- iOS中通讯录的开发
通讯录开发主要是获取用户手机中的联系人,进而可以在应用中添加好友 一 .如何访问通讯录 (1)在iOS9之前,有两个框架可以访问用户的通讯录 AddressBookUI.framework: 提供了联 ...
- ios开发 通讯录
一.通信录开发 通信录开发主要是获取用户手机中的联系人 通过获取用户的通信录,可以在应用中添加好友等 二.如何访问用户的通讯录 在iOS9之前,有2个框架可以访问用户的通讯录 目前需要适配iOS8,所 ...
随机推荐
- Octave下操作CH341
#include <octave/oct.h> #include <windows.h> #include <cstdint> #include <fstre ...
- 【c语言】使用gumbo解析HTML
之前使用过PHP的Simple HTML DOM简单地解析HTML但PHP终非我所熟悉的语言,虽然我并不对语言抱有绝对的执着= =(什么你不相信,好吧,不管你信不信,反正我是信了= =).虽然可以简单 ...
- go语言基础之指针做函数参数
1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(a, b int) { a, b = b, a fmt. ...
- 中国大学MOOC-陈越、何钦铭-数据结构-笔记
中国大学MOOC-陈越.何钦铭-数据结构-2017春 跟着<中国大学MOOC-陈越.何钦铭-数据结构-2017春>学习,平时练习一下pat上的作业外:在这里记录一下:平时学习视屏的收获. ...
- Largest Rectangle in Histogram leetcode java
题目: Given n non-negative integers representing the histogram's bar height where the width of each ba ...
- JAVASCRIPT校验大全[转]
var IsFireFox = document.getElementById &&! document.all;//判断是否为FireFox //页面里回车到下一控件的焦点 func ...
- CF 463D Gargari and Permutations [dp]
给出一个长为n的数列的k个排列(1 ≤ n ≤ 1000; 2 ≤ k ≤ 5).求这个k个数列的最长公共子序列的长度 dp[i]=max{dp[j]+1,where j<i 且j,i相应的字符 ...
- [置顶] Android异步加载数据库和多线程编程
Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发.尚未有统一中文名称,中国大陆地区较多人使用“安卓” ...
- UITabBarController — 标签视图控制器
UITabBarController - 标签视图控制器 UITabBarController 分为三层结构: (1).tab bar (2.)Custom Content (3.). Tab bar ...
- MySQL 动态sql语句运行 用时间做表名
1. 描写叙述 在使用数据的时候,我时候我们须要非常多数据库,并且想用时间来做表名以区分.可是MySQL在存储过程中不支持使用变量名来做表名或者列名. 比方,有一个表我们想以"2015-07 ...