内容概述
iOS给我们提供了四个框架来供我们使用:iOS9之前,有AddressBookUI.framework和AddressBook.framework,iOS9推出的ContactsUI.framework和Contacts.framework根据名称就可以区分一个有界面,一个无界面;
Contacts框架相对AddressBook框架来说,肯定要简单的多,如果不针对iOS9以前的版本进行适配,建议尽量使用Contacts框架;
同时针对AddressBook框架,也有一个比较好用的三方框架供大家选择使用
基本用法
1.AddressBookUI.framework
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
{
// 1.获取联系人
// ABPeoplePickerNavigationController是iOS9之前的框架,所以在使用的时候,如果使用的是9.0+的版本,会报警告
ABPeoplePickerNavigationController *ppnc = [[ABPeoplePickerNavigationController alloc] init];
// 2.设置联系人代理
ppnc.peoplePickerDelegate = self;
// 3.弹出联系人界面
[self presentViewController:ppnc animated:YES completion:nil];
}
/**
* 该方法在点击联系人的时候调用 调用之后会自动退出控制器
*
* @param peoplePicker 弹出来的联系人控制器
* @param person 联系人
*/
//- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
//{
// // 1.获取联系人的姓名
// CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
// CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
// // 注:这里存在内存泄露
// // (__bridge NSString *)这种桥接方式,只会将对象的所有权交给Foundation的引用使用
// // (__bridge_transfer NSString *)这种桥接方式,对象所有权都交给Foundation的引用,并且内存也交给它管理
// // 因此如果用(__bridge NSString *)这种桥接方式,在最后释放对象的时候,需要手动release掉
// NSString *firstNamed = (__bridge_transfer NSString *)(firstName);
// NSString *lastNamed = (__bridge_transfer NSString *)(lastName);
//
// NSLog(@"%@ %@",lastNamed,firstNamed);
//
// // 2.获取联系人的电话
//
// // 2.1 获取到所有电话
// ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
//
// CFIndex index = ABMultiValueGetCount(phones);
// // 2.2 遍历所有电话
// for (int i = 0; i < index; i++) {
// NSString *phoneNumber = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phones, i);
// NSString *phoneLabel =(__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(phones, i);
//
// NSLog(@"%@ %@",phoneLabel, phoneNumber);
// }
//
// // 释放不需要的对象
// CFRelease(phones);
//
//}
/**
* 该方法是在进入联系人详情界面的时候,点击联系人的各个属性会调用该方法
* 调用之后会自动退出控制器
* 注:两个代理方法不能同时调用 这个方法调用的时候,不能调用上面的代理方法
* @param peoplePicker 弹出来的联系人控制器
* @param person 联系人
* @param property 联系人属性
* @param identifier 标识
*/
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
}
2.AddressBook.framework
在获取到通讯录之前,先要对用户进行授权
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 判断用户是否授权
// kABAuthorizationStatusNotDetermined 未决定授权状态
// kABAuthorizationStatusRestricted 受系统保护,不能访问通讯录
// kABAuthorizationStatusDenied, 拒绝访问
// kABAuthorizationStatusAuthorized 确认授权
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusNotDetermined) {
// 创建通信录对象
ABAddressBookRef addressBook = ABAddressBookCreate();
// 请求授权
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(@"授权成功");
}else
{
NSLog(@"授权失败");
NSLog(@"%@",error);
}
});
}
return YES;
}
回到viewController,先判断是否授权,没有授权就直接return掉
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
{
// 获取通讯录的时候,先要判断是否进行授权
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
// 如果没有进行授权就return掉
if (status != kABAuthorizationStatusAuthorized) return;
// 获取所有的联系人
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
// 遍历联系人数组
CFIndex peopleCount = CFArrayGetCount(people);
for (int i = 0; i < peopleCount; i++) {
// 获取联系人姓名
ABRecordRef person = CFArrayGetValueAtIndex(people, i);
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
NSLog(@"%@ %@",lastName,firstName);
// 获取联系人电话
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex phoneCount = ABMultiValueGetCount(phones);
for (int i = 0; i < phoneCount; i++) {
// 获取电话号码
NSString *phoneNumber = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phones, i);
// 获取电话标签
NSString *phoneLabel = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(phones, i);
NSLog(@"%@ %@",phoneLabel,phoneNumber);
}
CFRelease(phones);
}
CFRelease(addressBook);
CFRelease(people);
}
3.ContactsUI.framework
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event
{
//创建通讯录界面
CNContactPickerViewController*cpvc = [[CNContactPickerViewControlleralloc]init];
//设置代理
cpvc.delegate=self;
//弹出通讯录界面
[selfpresentViewController:cpvcanimated:YEScompletion:nil];
}
- (void)contactPicker:(CNContactPickerViewController*)picker didSelectContact:(CNContact*)contact
{
//直接根据contact对象获取信息
NSString*firstName = contact.familyName;
NSString*lastName = contact.givenName;
NSLog(@"%@ ------ %@",lastName,firstName);
NSArray*phoneArray = contact.phoneNumbers;
for(CNLabeledValue*labelValueinphoneArray) {
CNPhoneNumber*value = labelValue.value;
NSString*phoneValue = value.stringValue;
NSString*phoneLabel = labelValue.label;
NSLog(@"%@ %@",phoneLabel,phoneValue);
}
}
4.Contacts.framework
在启动页,首先要进行授权
//授权状态
CNAuthorizationStatusstatus = [CNContactStoreauthorizationStatusForEntityType:CNEntityTypeContacts];
if(status ==CNAuthorizationStatusNotDetermined) {
//创建通讯录对象
CNContactStore*store = [[CNContactStorealloc]init];
//给用户授权
[storerequestAccessForEntityType:CNEntityTypeContactscompletionHandler:^(BOOLgranted,NSError*_Nullableerror) {
if(granted) {
NSLog(@"授权成功");
}else
{
NSLog(@"授权失败:%@",error);
}
}];
}
授权之后,就开始获取通讯录信息
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event
{
//判断是否授权
CNAuthorizationStatusstatus = [CNContactStoreauthorizationStatusForEntityType:CNEntityTypeContacts];
if(status !=CNAuthorizationStatusAuthorized)return;
//创建通信录对象
CNContactStore*store = [[CNContactStorealloc]init];
//获取所有的联系人
NSArray*keys =@[CNContactGivenNameKey,CNContactFamilyNameKey,CNContactPhoneNumbersKey];
CNContactFetchRequest*request = [[CNContactFetchRequestalloc]initWithKeysToFetch:keys];
[storeenumerateContactsWithFetchRequest:requesterror:nilusingBlock:^(CNContact*_Nonnullcontact,BOOL*_Nonnullstop) {
NSString*firstName = contact.familyName;
NSString*lastName = contact.givenName;
NSLog(@"%@ ------ %@",lastName,firstName);
NSArray*phoneArray = contact.phoneNumbers;
for(CNLabeledValue*labelValueinphoneArray) {
CNPhoneNumber*value = labelValue.value;
NSString*phoneValue = value.stringValue;
NSString*phoneLabel = labelValue.label;
NSLog(@"%@ %@",phoneLabel,phoneValue);
}
}];
}