一、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

最新文章

  1. 解析Jquery取得iframe中元素的几种方法
  2. 速度最快的Json序列框架Jil,入门动手实录
  3. Centos7安装图形界面
  4. Config文件
  5. leap motion
  6. poj1006_Biorhythms
  7. ASCII码常用值
  8. [HttpClient]HttpClient简介
  9. Linux_Shell type
  10. 距离变换DT
  11. Highcharts获取json数据展现pie饼图
  12. 分布式Ruby解决之道
  13. alert换行
  14. 一文带你看懂cookie,面试前端不用愁
  15. 梯度下降(gradient descent)算法简介
  16. angular2.0学习笔记2.创建hello world项目
  17. 【LOJ】 #2547. 「JSOI2018」防御网络
  18. ubuntu下安装ftp服务器
  19. Java 条件编译
  20. 管理 python logging 日志使用

热门文章

  1. SSH命令行传输文件到远程服务器
  2. java基础学习日志--String、StringBuffer方法案例
  3. 洛谷——P1516 青蛙的约会
  4. eclipse 中常用快捷键
  5. Python爬虫入门教程: 27270图片爬取
  6. NumPy 学习笔记(四)
  7. IDLE in Python (Ubuntu)
  8. [bzoj4567][Scoi2016][背单词] (贪心+trie树)
  9. Tensorflow Eager execution and interface
  10. CODEVS1022 覆盖 (二分图染色+匈牙利算法)