访问通讯录需要用户授权,开发人员需要在工程配置文件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 <UIKit/UIKit.h>
@interface ViewController:UITableViewController
@end
//ViewController.m文件
#import "ViewController.h"
#import "DetailViewController.h"
#import <Contacts/Contacts.h>
@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