.h文件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class PersonInfoModel;
typedef void(^AddressbookInfoBlock)(NSMutableArray<PersonInfoModel *> *personInfoArray);
@interface AddressbookManager : NSObject
// 手机授权App用户获取通讯录权限
+ (void)xl_addressbookAuthorization:(AddressbookInfoBlock)block;
@end
.m文件
#import "AddressbookManager.h"
#ifdef __IPHONE_9_0
#import <Contacts/Contacts.h>
#endif
#import <AddressBook/AddressBook.h>
#import "PersonInfoModel.h"
#define iOS9_LATER [[UIDevice currentDevice].systemVersion floatValue] >= 9.0 ? YES : NO
@implementation AddressbookManager
+ (void)xl_addressbookAuthorization:(AddressbookInfoBlock)block {
if (iOS9_LATER) { // 在iOS9之后获取通讯录用CNContactStore
// 已经授权了 直接返回
if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusAuthorized) {
[self xl_fetchAddressbookInformation:block];
return;
}
CNContactStore *contactStore = [[CNContactStore alloc] init];
[contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
[self xl_fetchAddressbookInformation:block];
}
else {
// 这里添加权限提示
}
}];
}
else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusAuthorized) { // 已经授权
[self xl_fetchAddressbookInformation:block];
return;
}
ABAddressBookRef addressbook = ABAddressBookCreateWithOptions(NULL, NULL);
ABAddressBookRequestAccessWithCompletion(addressbook, ^(bool granted, CFErrorRef error) {
if (granted) {
[self xl_fetchAddressbookInformation:block];
}
else {
// 这里添加权限提示
}
});
#pragma clang diagnostic pop
}
}
+ (void)xl_fetchAddressbookInformation:(AddressbookInfoBlock)block {
if (iOS9_LATER) {
[self xl_fetchAddressbookInformationWhenSystemVersionIsiOS9Later:block];
}
else {
[self xl_fetchAddressbookInformationWhenSystemVersionIsiOS9Before:block];
}
}
// iOS9.0 之后
+ (void)xl_fetchAddressbookInformationWhenSystemVersionIsiOS9Later:(AddressbookInfoBlock)block {
NSMutableArray *array = [NSMutableArray array];
CNContactStore *contactStore = [[CNContactStore alloc] init];
// 由keys决定获取联系人的那些信息: 姓名 手机号
NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
NSError *error = nil;
[contactStore enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
PersonInfoModel *model = [[PersonInfoModel alloc] init];
// 联系人姓名
NSString *name = [NSString stringWithFormat:@"%@%@", contact.familyName ? contact.familyName : @"", contact.givenName ? contact.givenName : @""];
model.personName = name ? name : @"熊猫";
// 联系人手机号
NSArray *phones = contact.phoneNumbers;
CNLabeledValue *labeledValue = phones.firstObject;
CNPhoneNumber *phone = labeledValue.value;
model.personPhone = phone.stringValue ? phone.stringValue : @"110";
[array addObject:model];
}];
// 把获取到的联系人信息传过去
block(array);
}
// iOS9.0 之前
+ (void)xl_fetchAddressbookInformationWhenSystemVersionIsiOS9Before:(AddressbookInfoBlock)block {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSMutableArray *array = [[NSMutableArray array] init];
// 创建通讯录对象
ABAddressBookRef addressbook = ABAddressBookCreateWithOptions(NULL, NULL);
// 从通讯录中将所有人的信息拷贝出来
CFArrayRef allPersonInfoArray = ABAddressBookCopyArrayOfAllPeople(addressbook);
// 获取联系人的个数
CFIndex personCount = CFArrayGetCount(allPersonInfoArray);
for (int i = 0; i < personCount; i++) {
PersonInfoModel *model = [[PersonInfoModel alloc] init];
// 获取其中每个联系人的信息
ABRecordRef person = CFArrayGetValueAtIndex(allPersonInfoArray, i);
// 联系人姓名
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *name = [NSString stringWithFormat:@"%@%@", lastName ? lastName : @"", firstName ? firstName :@""];
model.personName = name ? name : @"熊猫";
// 联系人电话
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonDepartmentProperty);
// 这里有可能 一个联系人 好几个手机号 (目前没有做处理)
// CFIndex phoneCount = ABMultiValueGetCount(phones);
NSString *phone = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phones, 0);
model.personPhone = phone ? phone : @"110";
CFRelease(phones);
[array addObject:model];
}
block(array);
CFRelease(allPersonInfoArray);
CFRelease(addressbook);
#pragma clang diagnostic pop
}
在文章中 PersonInfoModel 是一个自定义的数据模型类, 主要用来存储 联系人的信息