|
|
|
|
//
|
|
|
|
|
// PPDataHandle.m
|
|
|
|
|
// PPAddressBook
|
|
|
|
|
//
|
|
|
|
|
// Created by AndyPang on 16/8/17.
|
|
|
|
|
// Copyright © 2016年 AndyPang. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#import "PPAddressBookHandle.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@interface PPAddressBookHandle ()
|
|
|
|
|
|
|
|
|
|
#ifdef __IPHONE_9_0
|
|
|
|
|
/** iOS9之后的通讯录对象*/
|
|
|
|
|
@property (nonatomic, strong) CNContactStore *contactStore;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation PPAddressBookHandle
|
|
|
|
|
|
|
|
|
|
PPSingletonM(AddressBookHandle)
|
|
|
|
|
|
|
|
|
|
- (void)requestAuthorizationWithSuccessBlock:(void (^)(void))success
|
|
|
|
|
{
|
|
|
|
|
if(IOS9_LATER)
|
|
|
|
|
{
|
|
|
|
|
#ifdef __IPHONE_9_0
|
|
|
|
|
// 1.判断是否授权成功,若授权成功直接return
|
|
|
|
|
if ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusAuthorized) return;
|
|
|
|
|
// 2.创建通讯录
|
|
|
|
|
//CNContactStore *store = [[CNContactStore alloc] init];
|
|
|
|
|
// 3.授权
|
|
|
|
|
[self.contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
|
|
|
|
if (granted) {
|
|
|
|
|
NSLog(@"授权成功"); success();
|
|
|
|
|
}else{
|
|
|
|
|
NSLog(@"授权失败");
|
|
|
|
|
}
|
|
|
|
|
}];
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 1.获取授权的状态
|
|
|
|
|
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
|
|
|
|
|
// 2.判断授权状态,如果是未决定状态,才需要请求
|
|
|
|
|
if (status == kABAuthorizationStatusNotDetermined) {
|
|
|
|
|
// 3.创建通讯录进行授权
|
|
|
|
|
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
|
|
|
|
|
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
|
|
|
|
|
if (granted) {
|
|
|
|
|
NSLog(@"授权成功"); success();
|
|
|
|
|
} else {
|
|
|
|
|
NSLog(@"授权失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (void)getAddressBookDataSource:(PPPersonModelBlock)personModel authorizationFailure:(AuthorizationFailure)failure
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if(IOS9_LATER)
|
|
|
|
|
{
|
|
|
|
|
[self getDataSourceFrom_IOS9_Later:personModel authorizationFailure:failure];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[self getDataSourceFrom_IOS9_Ago:personModel authorizationFailure:failure];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - IOS9之前获取通讯录的方法
|
|
|
|
|
- (void)getDataSourceFrom_IOS9_Ago:(PPPersonModelBlock)personModel authorizationFailure:(AuthorizationFailure)failure
|
|
|
|
|
{
|
|
|
|
|
// 1.获取授权状态
|
|
|
|
|
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
|
|
|
|
|
|
|
|
|
|
// 2.如果没有授权,先执行授权失败的block后return
|
|
|
|
|
if (status != kABAuthorizationStatusAuthorized/** 已经授权*/)
|
|
|
|
|
{
|
|
|
|
|
failure ? failure() : nil;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3.创建通信录对象
|
|
|
|
|
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
|
|
|
|
|
|
|
|
|
|
//4.按照排序规则从通信录对象中请求所有的联系人,并按姓名属性中的姓(LastName)来排序
|
|
|
|
|
ABRecordRef recordRef = ABAddressBookCopyDefaultSource(addressBook);
|
|
|
|
|
CFArrayRef allPeopleArray = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, recordRef, kABPersonSortByLastName);
|
|
|
|
|
|
|
|
|
|
// 5.遍历每个联系人的信息,并装入模型
|
|
|
|
|
for(id personInfo in (__bridge NSArray *)allPeopleArray)
|
|
|
|
|
{
|
|
|
|
|
PPPersonModel *model = [PPPersonModel new];
|
|
|
|
|
|
|
|
|
|
// 5.1获取到联系人
|
|
|
|
|
ABRecordRef person = (__bridge ABRecordRef)(personInfo);
|
|
|
|
|
|
|
|
|
|
// 5.2获取全名
|
|
|
|
|
NSString *name = (__bridge_transfer NSString *)ABRecordCopyCompositeName(person);
|
|
|
|
|
model.name = name.length > 0 ? name : @"无名氏" ;
|
|
|
|
|
|
|
|
|
|
// 5.3获取头像数据
|
|
|
|
|
NSData *imageData = (__bridge_transfer NSData *)ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail);
|
|
|
|
|
model.headerImage = [UIImage imageWithData:imageData];
|
|
|
|
|
|
|
|
|
|
// 5.4获取每个人所有的电话号码
|
|
|
|
|
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
|
|
|
|
|
|
|
|
|
|
CFIndex phoneCount = ABMultiValueGetCount(phones);
|
|
|
|
|
for (CFIndex i = 0; i < phoneCount; i++)
|
|
|
|
|
{
|
|
|
|
|
// 号码
|
|
|
|
|
NSString *phoneValue = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phones, i);
|
|
|
|
|
NSString *mobile = [self removeSpecialSubString:phoneValue];
|
|
|
|
|
|
|
|
|
|
[model.mobileArray addObject: mobile ? mobile : @"空号"];
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// 5.5将联系人模型回调出去
|
|
|
|
|
personModel ? personModel(model) : nil;
|
|
|
|
|
|
|
|
|
|
CFRelease(phones);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 释放不再使用的对象
|
|
|
|
|
CFRelease(allPeopleArray);
|
|
|
|
|
CFRelease(recordRef);
|
|
|
|
|
CFRelease(addressBook);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - IOS9之后获取通讯录的方法
|
|
|
|
|
- (void)getDataSourceFrom_IOS9_Later:(PPPersonModelBlock)personModel authorizationFailure:(AuthorizationFailure)failure
|
|
|
|
|
{
|
|
|
|
|
#ifdef __IPHONE_9_0
|
|
|
|
|
// 1.获取授权状态
|
|
|
|
|
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
|
|
|
|
|
// 2.如果没有授权,先执行授权失败的block后return
|
|
|
|
|
if (status != CNAuthorizationStatusAuthorized)
|
|
|
|
|
{
|
|
|
|
|
failure ? failure() : nil;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 3.获取联系人
|
|
|
|
|
// 3.1.创建联系人仓库
|
|
|
|
|
//CNContactStore *store = [[CNContactStore alloc] init];
|
|
|
|
|
|
|
|
|
|
// 3.2.创建联系人的请求对象
|
|
|
|
|
// keys决定能获取联系人哪些信息,例:姓名,电话,头像等
|
|
|
|
|
NSArray *fetchKeys = @[[CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName],CNContactPhoneNumbersKey,CNContactThumbnailImageDataKey];
|
|
|
|
|
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:fetchKeys];
|
|
|
|
|
|
|
|
|
|
// 3.3.请求联系人
|
|
|
|
|
[self.contactStore enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact,BOOL * _Nonnull stop) {
|
|
|
|
|
|
|
|
|
|
// 获取联系人全名
|
|
|
|
|
NSString *name = [CNContactFormatter stringFromContact:contact style:CNContactFormatterStyleFullName];
|
|
|
|
|
|
|
|
|
|
// 创建联系人模型
|
|
|
|
|
PPPersonModel *model = [PPPersonModel new];
|
|
|
|
|
model.name = name.length > 0 ? name : @"无名氏" ;
|
|
|
|
|
|
|
|
|
|
// 联系人头像
|
|
|
|
|
model.headerImage = [UIImage imageWithData:contact.thumbnailImageData];
|
|
|
|
|
|
|
|
|
|
// 获取一个人的所有电话号码
|
|
|
|
|
NSArray *phones = contact.phoneNumbers;
|
|
|
|
|
|
|
|
|
|
for (CNLabeledValue *labelValue in phones)
|
|
|
|
|
{
|
|
|
|
|
CNPhoneNumber *phoneNumber = labelValue.value;
|
|
|
|
|
NSString *mobile = [self removeSpecialSubString:phoneNumber.stringValue];
|
|
|
|
|
[model.mobileArray addObject: mobile ? mobile : @"空号"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//将联系人模型回调出去
|
|
|
|
|
personModel ? personModel(model) : nil;
|
|
|
|
|
}];
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//过滤指定字符串(可自定义添加自己过滤的字符串)
|
|
|
|
|
- (NSString *)removeSpecialSubString: (NSString *)string
|
|
|
|
|
{
|
|
|
|
|
string = [string stringByReplacingOccurrencesOfString:@"+86" withString:@""];
|
|
|
|
|
string = [string stringByReplacingOccurrencesOfString:@"-" withString:@""];
|
|
|
|
|
string = [string stringByReplacingOccurrencesOfString:@"(" withString:@""];
|
|
|
|
|
string = [string stringByReplacingOccurrencesOfString:@")" withString:@""];
|
|
|
|
|
string = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
|
|
|
|
|
string = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
|
|
|
|
|
|
|
|
|
|
return string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - lazy
|
|
|
|
|
|
|
|
|
|
#ifdef __IPHONE_9_0
|
|
|
|
|
- (CNContactStore *)contactStore
|
|
|
|
|
{
|
|
|
|
|
if(!_contactStore)
|
|
|
|
|
{
|
|
|
|
|
_contactStore = [[CNContactStore alloc] init];
|
|
|
|
|
}
|
|
|
|
|
return _contactStore;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
@end
|