iOS 访问通讯录

访问通讯录需要用户授权,开发人员需要在工程配置文件Info.plist中添加NSContactsUsageDescription键

1、使用Contacts框架读取联系人信息

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]];
		}
	}
}
2、使用Contacts框架写入联系人信息

写入联系人相关的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);
	}
}
3、使用系统提供的界面ContactsUI

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版》

你可能感兴趣的:(ios)