您的位置:首页 > 移动开发 > IOS开发

iOS通讯录(纯纯的干货)

2016-04-28 20:05 597 查看
一、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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: