这篇文章主要介绍在iOS8.0和iOS9.0有界面和无界面 获取通讯录信息的方法.下面我们逐个介绍 首先我们要明确 无论是 iOS8.0和iOS9.0在有界面的情况下都不需要授权
1.iOS8.0 有界面的操作 需要导入 AddressBookUI 静态库 遵循 ABPeoplePickerNavigationControllerDelegate协议
需要注意的是我们在不用桥接的情况下要注意内存泄露问题
#import "ViewController.h"
#import <AddressBookUI/AddressBookUI.h>
@interface ViewController () <ABPeoplePickerNavigationControllerDelegate>
@end
@implementation ViewController
- (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
{
//目标: 获取联系人信息
//coreFountion
//指针 Record 记录 数据库 字段 列 记录 行
//需求 : name 电话号码
//C语言API特征 实现任何功能都是 调用一个函数 参数 返回值 输入和输出
// name
CFStringRef strfirst = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef strlast = ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *strF = (__bridge_transfer NSString *)(strfirst);
NSString *strL = (__bridge_transfer NSString *)(strlast);
NSLog(@"%@ %@",strF,strL);
//电话号码 ABMultiValueRef 封装一个保存了很多电话的一个类型
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);
}
//内存 静态分析工具
//C语言 API CoreFoundation create copy 等 获取 的对象都需要释放 -> CFRelease
//桥接
//__bridge 默认桥接
//__bridge_transfer 桥接 coreF -> ocF 转让对象的所有权
//__bridge_retained 桥接 ocF -> coreF 转让对象的所有权
}
/*备份*/ 在没有使用桥接的情况下注意内存泄露问题
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
//目标: 获取联系人信息
//coreFountion
//指针 Record 记录 数据库 字段 列 记录 行
//需求 : name 电话号码
//C语言API特征 实现任何功能都是 调用一个函数 参数 返回值 输入和输出
// name
CFStringRef strfirst = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef strlast = ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *strF = (__bridge NSString *)(strfirst);
NSString *strL = (__bridge NSString *)(strlast);
NSLog(@"%@ %@",strF,strL);
if (strfirst != NULL) {
CFRelease(strfirst);
}
if (strlast != NULL)
{
CFRelease(strlast);
}
//电话号码 ABMultiValueRef 封装一个保存了很多电话的一个类型
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 (strPhone != NULL) {
CFRelease(strPhone);
}
}
if (multiValues != NULL) {
CFRelease(multiValues);
}
//内存 静态分析工具
//C语言 API CoreFoundation create copy 等 获取 的对象都需要释放 -> CFRelease
//桥接
//__bridge 默认桥接
//__bridge_transfer 桥接 coreF -> ocF 转让对象的所有权
//__bridge_retained 桥接 ocF -> coreF 转让对象的所有权
}
//选择中 一个人的信息就会调用 必须是选择属性 才会调用
//注意点 如果实现 上面 peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person 当前方法不执行 界面不显示
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
NSLog(@"property %zd",property);
}
//点击取消了 就会调用
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
NSLog(@"peoplePickerNavigationControllerDidCancel");
}
2.iOS8.0 无界面的操作 需要导入 AddressBook 静态库 需要授权
#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) {
//参数1 通讯录对象 参数2block 回调
ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
//申请授权
ABAddressBookRequestAccessWithCompletion(book, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(@"授权成功!");
}else{
NSLog(@"授权失败!");
}
});
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取联系人 信息
//name
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);
}
}
}
3.iOS9.0 有界面的操作 需要导入 ContactsUI 静态库
#import "ViewController.h"
#import <ContactsUI/ContactsUI.h>
@interface ViewController ()<CNContactPickerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//不需要授权
//1.创建通讯录控制器
CNContactPickerViewController *picker = [[CNContactPickerViewController alloc]init];
//2.设置代理 拿到数据本身
picker.delegate = self;
//3.展示
[self presentViewController:picker animated:YES completion:nil];
}
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker;
{
NSLog(@"contactPickerDidCancel");
}
//选择一个联系人信息
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact;
{
NSLog(@"didSelectContact");
//NSLog(@"%@",contact.givenName);
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");
}
4.iOS9.0 无界面的操作 需要导入 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);
}];
}