通讯录
有两个框架可以访问用户的通讯录
AddressBookUI.framework
- 提供了联系人列表界面,联系人详情界面,添加联系人界面等
- 一般用于选择联系人
AddressBook.framework
- 纯 C 语言的 API ,仅仅是获得联系人数据
- 没有提供 UI 界面展示,需要自己搭建联系人展示界面
- 里面的数据类型大部分是基于 Core Foundation 框架,使用很头疼
从 iOS6开始,需要得到用户的授权才能访问通讯录,因此在使用之前,需要检查用户是否已经授权
- 请求授权
//1.获取授权状态 ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); //2.判断是否授权 if (status == kABAuthorizationStatusNotDetermined) { //3.创建通讯录 ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); //4.请求授权 ABAddressBookRequestAccessWithCompletion( addressBook, ^(bool granted, CFErrorRef error) { if (error) { NSLog(@"授权失败"); }else{ NSLog(@"授权成功"); } }); }
通讯录(带 UI)事例
#import "ViewController.h"
#import <AddressBookUI/AddressBookUI.h>
@interface ViewController ()<ABPeoplePickerNavigationControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//1.创建控制器
ABPeoplePickerNavigationController *peopleNavC = [[ABPeoplePickerNavigationController alloc] init];
peopleNavC.peoplePickerDelegate = self;
//2.弹出控制器
[self presentViewController:peopleNavC animated:YES completion:nil];
}
//
// Called after a person has been selected by the user.
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person{
CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
// //桥接方式1 -- 需要手动管理内存
// NSString *first = (__bridge NSString*)(firstName);
// NSString *lastt = (__bridge NSString*)(lastName);
//
// //释放方式1
// CFRelease(firstName);
// CFRelease(lastName);
//桥接方式2 -- 不需要手动管理内存 ---->转变为 ARC
// NSString *first = CFBridgingRelease( firstName);
// NSString *lastt = CFBridgingRelease( lastName);
//桥接方式2 -- 不需要手动管理内存 ---->转换对象管理权-- 交给 Foundation 管理
NSString *first = (__bridge_transfer NSString*)( firstName);
NSString *lastt = (__bridge_transfer NSString*)( lastName);
//桥接方式3 -- Foundation 框架-->Core Foundation
//CFStringRef firstRef = (__bridge_retained CFStringRef)first;
//获取电话
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
long count = ABMultiValueGetCount(phones);
for (int i = 0 ; i < count; i++) {
NSString * label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(phones, i));
NSString *value = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, i));
NSLog(@"%@,%@",label,value);
}
CFRelease(phones);
NSLog(@"%@:%@",first,lastt);
}
不带 UI 的通讯录(使用AddressBook.framework)
#import <AddressBook/AddressBook.h>
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
//1.获取所有通讯录的数据
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL);
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex count = CFArrayGetCount(people);
//2.选择某一个数据
for (int i = 0; i < count; i++) {
ABRecordRef record = CFArrayGetValueAtIndex(people, i);
NSString *firstName = CFBridgingRelease(ABRecordCopyValue(record, kABPersonFirstNameProperty));
NSLog(@"%@",firstName);
//获取所有电话数据
ABMultiValueRef phones = ABRecordCopyValue(record, kABPersonPhoneProperty);
CFIndex phonesCount = ABMultiValueGetCount(phones);
//遍历电话数据
for (int j = 0; j < phonesCount; j++) {
NSString *label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(phones, j));
NSString *value = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, j));
NSLog(@"%@,%@",label,value);
}
//释放 phones
CFRelease(phones);
}
//释放 people
CFRelease(people);
//释放addressBook
CFRelease(addressBook);
}
}
@end
iOS9通讯录使用
- 获取授权
//1.获取授权状态
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
//2.判断授权状态
if (status == CNAuthorizationStatusNotDetermined) {
//3.创建通讯录
CNContactStore *contact = [[CNContactStore alloc] init];
//4.发送请求
[contact requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (error) {
NSLog(@"授权失败");
}else{
NSLog(@"授权成功!");
}
}];
}
- 获取通讯录信息
#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{
//创建控制器
CNContactPickerViewController *cpVC = [[CNContactPickerViewController alloc] init];
//弹出控制器
[self presentViewController:cpVC animated:YES completion:nil];
cpVC.delegate = self;
}
-(void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{
//1.判断授权状态
if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusAuthorized) {
//获取名字
NSLog(@"%@.%@",contact.givenName,contact.familyName);
//获取电话号码
NSArray *phoneNumbers = contact.phoneNumbers;
for (CNLabeledValue *labeledValue in phoneNumbers) {
NSLog(@"%@--%@",labeledValue.label, labeledValue.value);
}
}
}
@end