访问通讯录需要用户授权,开发人员需要在工程配置文件Info.plist中添加NSContactsUsageDescription键
Contacts框架中常用类
CNContactStore,封装访问通讯录的接口,可以查询、保存通讯录信息。
CNContact,封装通讯录中联系恩信息数据,是数据库的一条记录。
CNGroup,封装通讯录组信息数据,一个组包含了多联系人的信息,一个联系人也可以隶属于多个组。
CNContainer,封装通讯录容器信息数据,一个容器包含多联系人的信息,但一个联系人只能隶属于一个容器。
查询联系人
从通讯录中查询联系人数据,主要是通过CNContactStore类的三个查询方法实现的。
(1)unifiedContactWithIdentifier:KeysToFetch:error:,通过联系人标识(CNContact的identifier属性)查询单个联系人(CNContact)。第二个参数是要查询联系人的属性集合,第三个参数error是返回的错误。Swift版没有error参数,如果出错,则抛出错误。
(2)unifiedContactsMatchingPredicate:keysToFetch:error:通过一个谓词(NSPredicate)定义逻辑查询条件,查询出单个联系人。
(3)enumerateContactsWithFetchRequest:error:usingBlock:通过一个联系人读取对象(CNContactFetchRequest)查询联系人集合。第三个参数是代码块,查询成功后回调这个代码块。
例:
Swift代码
// An highlighted block
import UIKit
import Contacts
class VieController:UITableViewController,UISearchBarDelegate,UISearchResultsUpdating{
var searchController:UISearchController!
//声明属性listContacts,装载联系人的数组集合。
var listContacts:[CNContact]!
override func viewDidLoad(){
super.viewDidLoad()
//实例化UISearchController
self.searchController=uiSearchController(searchResultsController:nil)
//设置self为更新搜索结果对象
self.searchController.searchResultsUpdater=self
//在搜索时将背景设置为灰色
self.searchController.dimsBackgroundDuringPresentation=false
//将搜索栏放到表视图的表头中
self.tableView.tableHeaderView=self.searchController.searchBar
//查询通讯录中的所有联系人,并刷新表视图。
DispatchQueue.global(qos:.utility).async{
//查询通讯录中的所有联系人
self.listContacts=self.findAllContacts()
DispatchQueue.main.async{
self.tableVeiw.reloadData()
}
}
}
//MARK: -- 查询通讯录中所有联系人
func findAllContacts()->[CNContact]{
//返回的联系人集合
var contacts=[CNContact]()
//声明要哈讯的联系人的属性集合,CNContactFamilyNameKey,CNContactGivenNameKey都是联系人属性。按照国人习惯,CNContactFamilyNameKey是姓氏,CNContactGivenNameKey是名字
let keysToFetch=[CNContactFamilyNameKey,CNContactGivenNameKey]
//实例化联系人读取对象CNContactFetchRequest,构造函数的参数是联系人的属性集合。
let fetchRequest=CNContactFetchRequest(keysToFetch:keysToFetch)
//实例化CNContactStore对象,通过CNContactStore对象,可以执行查询、插入和更新联系人信息的操作。CNContactStore是通讯录访问的核心类。
let contactStore=CNContactStore()
do{
//通过CNContactStore对象的enumerateContactsWithFetchRequest:error:usingBlock:方法查询联系人。Swift中,该语句必须放到do-try-catch语句中。
try contactStore.enumerateContacts(with:fetchRequest,usingBlocak:{
(contact,stop)->Void in
//将查询的contact对象添加到contacts集合中。
contacts.append(contact)
})
}catch let error as NSError{
print(error.localizedDescription)
}
return contacts
}
//MARK: --按照姓名查询通讯录中的联系人
func findContactsByName(_ searchName:String?)->[CNContact]{
//没有输入任何字符
if(searchName=nil || searchName!.characters.count==0){
//返回通讯录中的所有联系人
return self.findAllContacts()
}
let contactStore=CNContactStore()
let keysToFetch=[CNContactFamilyNameKey,CNContactGivenNameKey]
//通过CNContact对象调用predicateForContactsMatchingName:方法返回一个谓词对象NSPredicate。谓词对象封装了一个逻辑查询条件,这个条件是匹配所有的姓名属性。
let predicate=CNContact.predicateForContactsMatchingName(searchName!)
do{
//没有错误的情况下返回查询结果
let contacts=trycontactStore.unifiedContacts(matching:predicate,keysToFetch:keysToFetch as [CNKeyDescriptor])
return contacts
}catch let error as NSError{
print(error.localizedDescription)
//如果有错误发生,返回通讯录中的所有联系人
return self.findAllContacts()
}
}
}
ObjectiveC代码
// An highlighted block
//ViewController.h文件
#import
@interface ViewController:UITableViewController
@end
//ViewController.m文件
#import "ViewController.h"
#import "DetailViewController.h"
#import
@interface ViewController()<UISearchBarDelegate,UISearchResultsUpdating>
@property(strong,nonatomic) UISearchController*searchController;
//声明属性listContacts,装载联系人的数组集合。
@property(strong,nonatomic) NSArray *listContacts;
@end
@implementation ViewController
-(void)viewDidLoad{
[super viewDidLoda];
//实例化UISearchController
self.searchController=[[UISearchController alloc] initWithSearchResultsController:nil];
//设置self为更新搜索结果对象
self.searchController.searchResultsUpdate=self;
//在搜索时将背景设置为灰色
self.searchController.dimsBackgroundDuringPresentation=FALSE;
//将搜索栏放到表视图的表头中
self.tableView.tableHeaderView=self.searchController.searchBar;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
//查询通讯录中的所有联系人
self.listContacts=[self findAllContacts];
dispatch_async(dispatch_get_main_queue(),^{
[self.tableView reloadData];
});
});
}
#pragma mark --查询通讯录中所有联系人
-(NSArray*)findAllContacts{
//返回的联系人集合
id contacts=[[NSMutableArray alloc] init];
//声明要查询的联系人的属性集合,CNContactFamilyNameKey,CNContactGivenNameKey都是联系人属性。
NSArray *keysToFetch=@[CNContactFamilyNameKey,CNContactGivenNameKey];
//实例化联系人读取对象CNContactFetchRequest,构造函数的参数是联系人的属性集合。
CNContactFetchRequest *fetchRequest=[[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch];
//实例化CNContactStore对象。通过CNContactStore对象可以执行查询、插入、更新联系人信息。
CNContactStore *contactStore=[[CNContactStore alloc] init];
NSError *error=nil;
//通过CNContactStore对象的enumerateContactsWithFetchRequest:error:usingBlock:方法查询联系人。Swift中,该语句必须放到do-try-catch语句中。
[contactStore enumerateContactsWithFetchRequest:fetchRequest error:&error usingBlock:^(CNContact *_Nonnull contact,BOOL *_Nonnull stop){
if(!error){
//查询语句执行成功的情况,将查询的contact对象添加到contacts集合中。
[conacts addObject:contact];
}else{
NSLog(@"error:%@",error.localizedDescription);
}
}];
return contacts;
}
#pragma mark --按照姓名查询通讯录中的联系人
-(NSArray *)findContactsByName:(NSString *)searchName{
//没有输入任何字符
if([searchName length]==0){
//返回通讯录中的所有联系人
return [self findAllContacts];
}
CNContactStore *contactStore=[[CNContactStore alloc] init];
NSArray *keysToFetch=@[CNContactFamilyNameKey,CNContactGivenNameKey];
//通过CNContact对象diaoyongpredicateForContactsMatchingName:方法返回一个谓词对象NSPredicate,谓词对象封装了一个逻辑查询条件,这个条件是匹配所有的姓名属性。
NSPredicate *predicate=[CNContact predicateForContactsMatchingNameLsearchName];
NSError *error=nil;
id contacts=[contactStore unifiedContactsMatchingPredicate:predicate keysToFetchLkeysToFetch error:&error];
if(!error){
//没有错误的情况下返回查询结果
return contacts;
}else{
//如果有错误发生,返回通讯录中的所有联系人
return [self findAllContacts];
}
}
@end
读取单值属性
一个联系人(CNContact)信息中有很多属性,这些属性有单值属性和多值属性之分。单值属性是只有一个值得户型,如姓氏和名字。常用的属性如下:
(1)givenName,名字
(2)familyName,姓氏
(3)middleName,中间名
(4)namePrefix,前缀
(5)nameSuffix,后缀
(6)nickname,昵称
(7)phoneticGivenName,名字汉语拼音或音标
(8)phoneticFamilyName,姓氏汉语拼音或音标
(9)phoneticMiddleName,中间名汉语拼音或音标
(10)organizationName,组织名
(11)jobTitle,头衔
(12)departmentName,部门
(13)note,备注
例:
Swift代码
// An highlighted block
override func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)->UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier:"Cell",for:indexPath)
//从集合属性listContacts取出CNContact对象
let contact=self.listContacts[indexPath.row]
//取出givenName属性
let firstName=contact.giveName
//取出联系人的familyName属性
let lastName=contact.familyName
let name="\(firstName)\(lastName)"
cell.textLabel!.text=name
return cell
}
ObjectiveC代码
// An highlighted block
-(UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
CNContact *contact=self.listContacts[indexPath.row];
NSString *firstName=contact.givenName;
NSString *lastName=contact.familyName;
NSString *name=[NSString stringWithFormat:@"%@ %@",firstName,lastName];
cell.textLabel.text=name;
return cell;
}
读取多值属性
多值属性是包含多个值得集合类型,如电话号码、电子邮箱和URL等。
(1)phoneNumbers,电话号码属性
(2)emailAddresses,电子邮箱属性
(3)urlAddresses,URL属性
(4)postalAddresses,地址属性
(5)instantMessageAddresses,即时聊天属性
(6)socialProfiles,社交账号属性
这些属性都是只读的CNLabeledValue集合类型。CNLabeledValue类型中的label(标签)、value(值)和identifier(ID)等部分,其中标签和值都是可以重复的,ID不能重复。
例:
Swift代码
// An highlighted block
override func viewDidLoad(){
super.viewDidLoad()
let contactStore=CNContactStore()
//要查询的联系人的属性集合。
let keysToFetch=[CNContactFamilyNameKey,CNContactGivenNameKey,CNContactEmailAddressesKey,CNContactPhoneNumbersKey,CNContactImageDataKey]
do{
//通过CNContactStore对象调用unifiedContactWithIdentifier:keysToFetch:error:方法执行查询,第一个餐胡是联系人标识,self.selectContact.identifier表达式用于获得联系人标识。
let contact=try contactStore.unifiedContact(withIdentifier:self.selectContact.identifier,keysToFetch:keysToFetch as [CNKeyDescriptor])
//保存查询出的联系人
self.selectContact=contact
//取出姓名属性
let firstName=contact.givenName
let lastName=contact.familyName
let name="\(firstName)\(lastName)"
self.lblName.text=name
//获取电子邮件属性,返回值是CNLabeledValue类型的数组集合。
let emailAddresses=contact.emailAddresses
for emailProperty in emailAddresses{
//是否是工作电子邮件
if emailProperty.label==CNLabelWork{
self.lblWorkEmail.text=emailProperty.value as String
//是否是家庭电子邮件
}else if emailProperty.label=CNLabelHome{
self.lblHomeEmail.text=emailProperty.value as String
}else{
print("其他Email:\(emailProperty.value)")
}
}
//获取电话号码属性
let phoneNumbers=contact.phoneNumbers
for phoneNumberProperty in phoneNumbers{
let phoneNumber =phoneNumberProperty.values as! CNPhoneNumber
/*
CNLabelPhoneNumberMain,主要电话号码标签。
CNLabelPhoneNumberHomeFax,家庭传真电话号码标签
CNLabelPhoneNumberWorkFax,工作传真电话号码标签
*/
if phoneNumberProperty.label==CNLabelPhoneNumberMobile{
self.lblMobile.text=phoneNumber.stringValue
}else if phoneNumberProperty.label=CNLabelPhoneNumberiPhone{
self.lblIPhone.text=phoneNumber.stringValue
}else {
print("其他电话:\(phoneNumber.stringValue)")
}
}
//读取图片属性,imageData属性是NSData类型
if let photoData=contact.imageData{
self.imageView.image=UIImage(data:photoData)
}
}catch let error as NSError{
print(error.locaizeDescription)
}
}
ObjectiveC代码
// An highlighted block
-(void)viewDidLoad{
[super viewDidLoad];
CNContactStore *contactStore=[[CNContactStore alloc] init];
//要查询的联系人的属性集合。
NSArray *keysToFetch=@[CNContactFamilyNameKey,CNContactGivenNameKey,CNContactEmailAddressesKey,CNContactPhoneNumbersKey,CNContactImageDataKey];
NSError *error=nil;
CNContact *contact=[contactStore unifiedContactWithIdentifier:self.selectContact.identifier keysToFetch:keysToFetch error:&error];
//保存查询出的联系人
self.selectContact=contact;
if(!error){
//取出姓名属性
NSString *firstName=contact.givenName;
NSString *lastName=contact.familyName;
NSString *name=[NSString stringWithFormat:@"%@ %@",firstName,lastName];
[self.labName setText:name];
//取得电子邮件属性,返回类型是NSArray*>,返回值是CNLabeledValue类型的数组集合。
NSArray<CNLabeledValue<NSString *>*>*emailAddresses=contact.emailAddresses;
for(CNLabeledValue<NSSting*>*emailProperty in emailAddresses){
//判断工作电子邮件
if([emailProperty.label isEqualToString:CNLabelWork]){
[self.lblWorkEmail setTextLemailProperty.value];
//判断家庭电子邮件
}else if([emailProperty.label isEqualToString:CNLabelHome]){
[self.lblHomeEmail setText:emailProperty.value];
}else{
NSLog(@"%@ %@",@"其他Email",emailProperty.value);
}
}
//获取电话号吗属性
NSArray<CNLabeleValue<CNPhoneNumber*>*>*phoneNumbers=contact.phoneNumbers;
for(CNLabeleValue<CNPhoneNumber*>*phoneNumberProperty in phoneNumbers){
/*
CNLabelPhoneNumberMain,主要电话号码标签。
CNLabelPhoneNumberHomeFax,家庭传真电话号码标签
CNLabelPhoneNumberWorkFax,工作传真电话号码标签
*/
CNPhoneNumber *phoneNumber=phoneNumberProperty.value;
if([phoneNumberProperty.label isEqualToString:CNLabelPhoneNumberMobile]){
[self.lblMobile setText:phoneNumber.stringValue];
}else if([phoneNumberProperty.label isEqualToString:CNLabelPhoneNumberiPhone]){
[self.lblIphone setText:phoneNumber.stringValue];
}else{
NSLog(@"%@ %@",@"其他电话",phoneNumber.stringValue);
}
}
//读取图片属性,imageData属性是NSData类型
NSData *phoneData=contat.imageData;
if(photoData){
[self.imageView setImage:[UIImage imageWithData:photoData]];
}
}
}
写入联系人相关的API有CNMutableContact和CNSaveRequest。其中,CNMutableContact是可变联系人对象,所有的写入联系人操作都必须放到CNMutableContact中;CNSaveRequest是保存请求对象,通过该对象指定对联系人进行创建、修改和删除操作。
创建联系人
例:
Swift代码
// An highlighted block
@IBAction func saveClick(_ sender:AnyObject){
//创建可变联系人对象CNMutableContact
let contact=CNMutableContact()
//这是姓名属性,设置姓名中的familyName属性,它是单值属性
contact.familyName=self.txtFirstName.text!
contact.giveName=self.txtLastName.text!
//设置电话号码,设置多值属性phoneNumbers,是一个集合,每个元素都是CNLabeledValue形式的泛型类型,CNLabeledValue中的值是CNPhoneNumber类型,不是普通的字符串类型。
//创建CNPhoneNumber对象
let mobilePhoneValue=CNPhoneNumber(stringValue:self.txtMobile.text!)
//创建移动电话CNLabeledValue对象,其中CNLabelPhoneNumberMobile是标签。
let mobilePhone=CNLabeledValue(label:CNLabelPhoneNumberMobile,value:mobilePhoneValue)
let iPhoneValue=CNPhoneNumber(stringValue:self.txtIPhone.text!)
let iPhone=CNLabeledValue(label:CNLabelPhoneNumberiPhone,value:iPhoneValue)
//添加电话号码到数据库,将CNLabeledValue对象集合赋值给phoneNumbers属性
contact.phoneNumbers=[mobilePhone,iPhone]
//设置电子邮件属性
let homeEmail=CNLabeledValue(label:CNLabelHome,value:self.txtHomeEmail.text! as NSString)
let workEmail=CNLabeledValue(label:CNLabelWork,value:self.txtWorkEmail.text! as NSString)
//添加电子邮件到数据库
contact.emailAddresses=[homeEmail,workEmail]
//最后后保存
//创建保存请求对象CNSaveRequest
let request=CNSaveRequet()
//设置插入操作的类型,方法addContact:toContainerWithIdentifier:表示插入联系人的操作,第一个参数是联系人对象,第二个参数是所在容器的ID,nil表示默认容器。
request.addContact(contact,toContainerWithIdentifier:nil)
let contactStore=CNContactStore()
//调用executeSaveRequest:error:方法,执行插入操作
do{
try contactStore.execute(request)
//关闭静态视图
self.dismiss(animated:true,completion:nil)
}catch let error as NSError{
print(error.localizedDescription)
}
}
ObjectiveC代码
// An highlighted block
-(IBAction)saveClick:(id)sender{
CNMutableContact* contact=[[CNMutableContact alloc] init];
//设置姓名属性
contact.familyName=self.txtFirstName.text;
contact.givenName=self.txtLastName.text;
//设置电话号码
CNPhoneNumber* mobilePhoneValue=[[CNPhoneNumber alloc] initWithStringValue:self.txtMobile.text];
CNLabeledValue *mobilePhone=[[CNLabeledValue alloc] initWithStringValue:self.txtMobile.text];
CNPhoneNumber* iPhoneValue=[[CNPhoneNumber alloc] initWithStringValue:self.txtIPhone.text];
CNLabeledValue* iPhone=[[CNLabeledValue alloc] initWithLabel:CNLabelPhoneNumberiPhone value:iPhoneValue];
//添加电话号码到数据库
contact.phoneNumbers=@[mobilePhone,iPhone];
//设置电子邮件属性
CNLabeledValue* homeEmail=[[CNLabeledValue alloc] initWithLabel:CNLabelHome value:self.txtHomeEmail.text];
CNLabeledValue* workEmail=[[CNLabeledValue alloc] initWithLabel:CNLabelWork value:self.txtWorkEmail.text];
//添加电子邮件到数据库
contact.emailAddresses=@[homeEmail,workEmail];
//最后保存
CNSaveRequest* request=[[CNSaveRequest alloc] init];
[request addContact:contact toContainerWithIdentifier:nil];
CNContactStore *contactStore=[[CNContactStore alloc] init];
NSError *error;
[ContactStore executeSaveRequest:request error:&error];
if(!error){
//关闭模态视图
[self dismissViewControllerAnimated:TRUE comletion:nil];
}else {
NSLog(@"error:%@",error.localizedDescription);
}
}
修改联系人
例:
Swift代码
// An highlighted block
@IBAction func saveClick(_ sender:AnyObject){
//获得可变联系人对象CNMutableContact,它不是实例化获得,是通过self.selectContact属性赋值出来的,mutableCopy方法复制出一个可变类型
let contact=self.selectContact.mutableCopy() as! CNMutableContact
//设置电话号码
let mobilePhoneValue=CNPhoneNumber(stringValue:self.txtMobile.text)
let mobilePhone=CNLabeledValue(label:CNLabelPhoneNumberMobile,value:mobilePhoneValue)
let iPhoneValue=CNPhoneNumber(stringValue:self.txtIphone.text)
let iPhone=CNLabeledValue(label:CNLabelPhoneNumberiPhone,value:iPhoneValue)
//添加电话号码到数据库
contact.phoneNumbers=[mobilePhone,iPhone]
//设置电子邮件属性
let homeEmail=CNLabeledValue(label:CNLabelHome,value:self.txtHomeEmail.text! as NSString)
let workEmail=CNLabeledValue(label:CNLabelWork,value:selftxtWorkEmail.text! as NSString)
//添加电子邮件到数据库
contact.emailAddresses=[homeEmail,workEmail]
//最后保存
let request=CNSaveRequest()
//设置修改操作类型
request.update(contact)
let contactStore=CNContactStore()
do{
try contactStore.execute(requet)
}catch let error as NSError{
print(error.localizedDescription)
}
}
ObjectiveC代码
// An highlighted block
-(IBAction)saveClick:(id)sender{
CNMutableContact* contact=[self.selectContact mutableCopy];
//设置电话号码
CNPhoneNumber *mobilePhoneValue=[[CNPhoneNumber alloc] initWithStringValue:self.txtMobile.text];
CNLabeledValue*mobilePhone=[[CNLabeledValue alloc] initWithLabel:CNLabelPhoneNumberMobile value:mobilePhoneValue];
CNPhoneNumber* iPhoneValue=[[CNPhoneNumber alloc] initWithStringValue:self.txtIphone.text];
CNLabeledValue*iPhone=[[CNLabeledValue alloc] initWithLabel:CNLabelPhoneNumberiPhone value:iPhoneValue];
//添加电话号码到数据库
contact.phoneNumbers=@[homeEmail,workEmail];
//最后保存
CNSaveRequest*request=[[CNSaveRequest alloc] init];
[request updateContact:contact];
CNContactStore *contactStore=[[CNContactStore alloc] init];
NSError*error;
[contactStore executeSaveRequest:request error:&error];
if(!error){
//TODO
}else{
NSLog(@"error:%@",error.localizedDescription);
}
}
删除联系人
例:
Swift代码
// An highlighted block
@IBAction func deleteClick(_ sender:AnyObject){
let contact=self.selectContact.mutableCopy() as! CNMutableContact
let request=CNSaveRequest()
request.delete(contact)
let contactStore=CNContactStore()
do{
try ContactStore.execute(request)
}
catch let error as NSError{
print(error.localizedDescription)
}
}
ObjectiveC代码
// An highlighted block
-(IBAction)deleteClick:(id)sender{
CNMutableContact* contact=[self.selectContact mutableCopy];
CNSaveRequest* request=[[CNSaveRequest alloc] init];
[request deleteContact:contact];
CNContactStore *contactStore=[[CNContactStore alloc] init];
NSError*error;
[contactStore executeSaveRequest:request error:&error];
if(!error){
//TODO
}else{
NSLog(@"error:%@",error.localizedDescription);
}
}
ContactsUI框架中的视图控制器
(1)CNContactPickerViewController,从通讯录中选取联系人的空间,对应的委托协议为CNContactPickerDelegate
(2)CNContactViewController,查看、创建爱你、编辑单个联系人信息的控制器,对应的委托协议是CNContactViewControllerDelegate
选择联系人
CNContactPickerViewController对应的委托协议CNContactPickerDelegate,定义了5个主要方法:
(1)contactPickerDidCancel:,点击联系人选取界面中的Cancel按钮时调用
(2)contactPicker:didSelectContact:,选中单个联系人时调用
(3)contactPicker:didSelectContactProperty:,选中单个联系人的属性时调用
(4)contactPicker:didSelectContacts:,选中多个联系人时调用
(5)contactPicker:didSelectContactProperties:,选中多个联系人的属性时调用
例:
Swift代码
// An highlighted block
//ViewController.swift文件
import UIKit
import ContactsUI
class ViewController:UITableViewController,CNContactPrickerDelegate{
var listContacts:[CNContact]!
override func viewDidLoad(){
super.viewDidLoad()
self.listContacts=[CNContact]()
}
@IBAction func selectContacts(_ sender:AnyObject){
//实例化CNContactPickerViewController联系人视图控制器对象
let contactPicker=CNContactPickerViewController()
contactPicker.delegate=self
//选择联系人属性时能够看到的属性
contactPicker.displayedPropertyKeys=[CNContactPhoneNumbersKey]
//模态视图形式呈现联系人选择界面。
self.present(contactPicker,animated:true,completion:nil)
}
//MARK:--表视图数据源
override func tableVeiw(_ tableView:UITableView,numberOfRowsInSection section:Int)->Int{
return self.listContacts.cont
}
override func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)->UITableViewCell{
let cell=tableView.dequeueReusableCell(withIdentifier:"Cell",for:indexPath)
let contact=self.listContacts[indexPath.row]
let firstName=contact.givenName
let lastName=contact.familyName
let name="\(firstName)\(lastName)"
cell.textLabel!.text=name
return cell
}
//实现CNContactPrickerDelegate委托协议中的contactPricker:didSelectContact:方法
func contactPicker(_ picker:CNContactPickerViewController,didSelect contact:CNContact){
if !self.listContacts.contains(contact){
self.listContacts.append(contact)
self.tableView.reloadData()
}
}
//实现CNContactPrickerDelegate委托协议中的contactPicker:didSelectContacts:方法
func contactPicker(_ picker:CNContactPickerViewController,didSelectcontacts:[CNContact]){
for contact in contacts where !self.listContacts.contains(contact){
self.listContacts.append(contact)
}
self.tableVeiw.reloadData()
}
}
ObjectiveC代码
// An highlighted block
//ViewController.m文件
#import "ViewController.h"
#import
@interface ViewController()<CNContactPickerDelegate>
@property(strong,nonatomic)NSMutableArray *listContacts;
@end
@implementation ViewController
-(void)viewDidLoad{
[super viewDidLoad];
self.listContacts=[[NSMutableArray alloc] init];
}
-(IBAction)selectContacts:(id)sender{
CNContactPickerViewController *contactPicker=[[CNContactPickerViewController alloc] init];
contactPicker.delegate=self;
contactPicker.displayedPropertyKeys=@[CNContactPhoneNumbersKey];
[self presentViewController:contactPicker animated:TRUE completion:nil];
}
#pragma mark --实现表视图数据源协议
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.listContacts count];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
CNContact *contact=self.listContacts[indexPath.row];
NSString *firstName=contact.givenName;
NSString *lastName=contact.familyName;
NSString *name=[NSString stringWithFormat:@"%@ %@",firstName,lastName];
cell.textLabel.text=name;
return cell;
}
//实现CNContactPrickerDelegate委托协议中的contactPricker:didSelectContact:方法
-(void)contactPicker:(CNContactPickerViewController*)picker didSelectContact:(CNContact*)contact{
if(![self.listContacts containsObject:contact]){
[self.listContacts addObject:contact];
[selftableView reloadData];
}
}
//实现CNContactPrickerDelegate委托协议中的contactPicker:didSelectContacts:方法
-(void)contactPicker:(CNContactPickerViewController*)picker didSelectContacts:(NSArray<CNContact*>*)contacts{
for(CNContact *contact in contacts){
if(![sel.listContacts containsObject:contact]){
[self.listContacts addObject:contact];
}
}
[self.tableView reloadData];
}
@end
参考资料
《IOS开发指南 从HELLO WORLD到APP STORE上架 第5版》