iOS通讯录(纯纯的干货)
一、iOS8.0
1、访问用户通讯录的两个框架
(1)AddressBookUI.framework
提供了联系人列表界面、联系人详情界面、添加联系人界面等,一般用于选择联系人
(2)AddressBook.framework
<1>纯C语言的API,仅仅是获得联系人数据
<2>没有提供UI界面展示,需要自己搭建联系人展示界面
<3>里面的数据类型大部分基于Core Foundation框架,使用起来非常不方便
(3)从iOS6开始,需要得到用户的授权才能访问通讯录(没UI界面的),因此在使用之前,需要检查用户是否已经授权
获得通讯录的授权状态:ABAddressBookGetAuthorizationStatus()
2、使用AddressBookUI.framework示例
#import "ViewController.h"
#import <AddressBookUI/AddressBookUI.h>
@interface ViewController () <ABPeoplePickerNavigationControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//创建通讯录控制器
//弹出控制器
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc]init];
//设置代理
picker.peoplePickerDelegate = self;
//展示通讯录界面
[self presentViewController:picker animated:YES completion:nil];
}
//选中一个人的基本信息就会调用
//参数1:控制器 参数2:选择的person的信息
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
/*
1、关于内存的管理:静态分析工具
2、因为是C语言的API(CoreFoundation),所有使用了create、copy等获取的对象都需要释放 -> CFRelease
3、桥接
__bridge 默认桥接
__bridge_transfer 桥接 coreF -> ocF 转让对象的所有权(释放权)
__bridge_retained 桥接 ocF -> coreF 转让对象的所有权
*/
//返回的ABRecordRef是一条记录,包括了一个人的所有信息字段
//通过“函数”获得姓名
CFStringRef strfirst = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef strlast = ABRecordCopyValue(person, kABPersonLastNameProperty);
//在桥接时,转让了对象的所有权,转给了OC来管理(自动释放了)
NSString *strF = (__bridge_transfer NSString *)(strfirst);
NSString *strL = (__bridge_transfer NSString *)(strlast);
NSLog(@"%@ %@",strF,strL);
//电话号码:ABMultiValueRef 封装一个保存了很多电话的一个类型,类似OC中的数组
ABMultiValueRef multiValues = ABRecordCopyValue(person, kABPersonPhoneProperty);
//获得这个集合的数量(电话号码的数量)
CFIndex index = ABMultiValueGetCount(multiValues);
//遍历集合,打印电话
for (CFIndex i = 0; i < index; i++) {
CFStringRef strPhone = ABMultiValueCopyValueAtIndex(multiValues, i);
NSString *phoneStr = (__bridge_transfer NSString *)(strPhone);
NSLog(@"%@",phoneStr);
}
//释放内存前,先判断该字段存在
if (multiValues != NULL) {
CFRelease(multiValues);
}
}
//选择中一个人信息的属性才会调用
//注意点:如果实现“选中个人信息的代理方法” 当前方法不执行,因为属性界面不会显示
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
NSLog(@"property %zd",property);
}
//点击取消了 就会调用
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
NSLog(@"peoplePickerNavigationControllerDidCancel");
}
3、使用AddressBook.framework框架示例
#import "ViewController.h"
#import <AddressBook/AddressBook.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//获取用户的授权:授权状态
/*
kABAuthorizationStatusNotDetermined = 0, // deprecated, use CNAuthorizationStatusNotDetermined
kABAuthorizationStatusRestricted, // deprecated, use CNAuthorizationStatusRestricted
kABAuthorizationStatusDenied, // deprecated, use CNAuthorizationStatusDenied
kABAuthorizationStatusAuthorized // 已经授权
*/
//通过函数获得授权状态
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusNotDetermined) {
ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
//申请授权
//参数1 通讯录对象 参数2block 回调
ABAddressBookRequestAccessWithCompletion(book, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(@"授权成功!");
}else{
NSLog(@"授权失败!");
}
});
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取联系人信息
//获得姓名
//通讯录是单例,在哪里获取都是一样的
ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
//获取所有人的信息
CFArrayRef allpeople = ABAddressBookCopyArrayOfAllPeople(book);
//数量
CFIndex count = CFArrayGetCount(allpeople);
for (CFIndex i = 0; i <count ; i++) {
//获得没一条记录
ABRecordRef record = CFArrayGetValueAtIndex(allpeople, i);
//获得姓名
CFStringRef strFirst = ABRecordCopyValue(record, kABPersonFirstNameProperty);
NSString *str = (__bridge_transfer NSString *)strFirst;
NSLog(@"%@",str);
//获得电话号码
ABMultiValueRef multivalue = ABRecordCopyValue(record, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multivalue); i++) {
CFStringRef phoneStr = ABMultiValueCopyValueAtIndex(multivalue, i);
NSString *phone = (__bridge_transfer NSString *)(phoneStr);
NSLog(@"%@",phone);
}
CFRelease(multivalue);
}
CFRelease(allpeople);
CFRelease(book);
}
@end
二、iOS9.0
1、访问用户通讯录的两个框架
(1)ContactsUI
<1>AddressBookUI的升级,不需要授权
<2>通过代理返回需要的数据
(2)Contacts
AddressBook.framework 的升级
2、ContactsUI示例
#import "ViewController.h"
#import <ContactsUI/ContactsUI.h>
@interface ViewController ()<CNContactPickerDelegate>
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//不需要授权
//创建通讯录控制器
CNContactPickerViewController *picker = [[CNContactPickerViewController alloc]init];
//设置代理拿到数据本身
picker.delegate = self;
//展示通讯录
[self presentViewController:picker animated:YES completion:nil];
}
//实现代理方法
//选择一个联系人的基本信息
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact;
{
//重点注意contact的类型和属性
NSArray *allArray = contact.phoneNumbers;
for (CNLabeledValue * labeledValue in allArray) {
CNPhoneNumber *num = labeledValue.value;
NSLog(@"num = %@",num.stringValue);
NSLog(@"===%@ ===%@",labeledValue.value,labeledValue.label);
}
}
//选择一个联系人属性信息
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;
{
NSLog(@"didSelectContactProperty");
}
@end
3、Contacts示例
#import "ViewController.h"
#import <Contacts/Contacts.h>
@interface ViewController ()
@property (nonatomic, strong) CNContactStore *store;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//获取授权状态
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
//如果没有授权过需要请求用户的授权
CNContactStore *store = [[CNContactStore alloc]init];
self.store = store;
if (status == CNAuthorizationStatusNotDetermined) {
//请求授权
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@"授权成功!");
}else{
NSLog(@"授权失败!");
}
}];
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//name phone
CNContactFetchRequest *request = [[CNContactFetchRequest alloc]initWithKeysToFetch:@[CNContactGivenNameKey,CNContactPhoneNumbersKey]];
//参数1 封装查询请求
[self.store enumerateContactsWithFetchRequest: request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
//返回的数据 CNContact
NSLog(@"%@",contact.givenName);
NSLog(@"%@",contact.phoneNumbers);
}];
}
@end

浙公网安备 33010602011771号