iOS:通信录(完成)(18-01-18更)
1、读取通信录
1)、9.0以前:AddressBook
2)、9.0以后:Contacts
2、调用通信录UI(不弄)
1)、9.0以前:AddressBookUI
2)、9.0以后:ContactsUI
3、参考
0、写在前面
1)、plist 需要设置 隐私权限描述
NSContactsUsageDescription(Privacy - Contacts Usage Description) :请求访问通讯录(自定义)
2)、一般应用只需要电话就够了,不过,如果想做 坏事 大数据分析,可能还是要全读取给后台吧?
3)、9.0后的 Contacts 类:
3-1)、如果请求数据的数组里没有该Key,但在 block 判断有,会奔溃。
3-2)、请求类型key,有10.0后的,需要注意,做判断。
4)、原生UI不打算弄了,感觉一般都是自定义UI,比如:有注册的在上面,添加好友按钮,没注册的在下面,邀请好友按钮。
5)、有空再整理成 单例manage。
1、读取通信录
1)、9.0以前
1-1)、头文件
#import <AddressBook/AddressBook.h>
1-2)、判断是否有权限
- (void)DetermineAndReadAddressBook { // 判断是否授权 ABAuthorizationStatus authorizationStatus = ABAddressBookGetAuthorizationStatus(); if (authorizationStatus == kABAuthorizationStatusNotDetermined) { // 请求授权 ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL); ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error){ if (granted) { // 授权成功 [self readAddressBook]; } else { // 授权失败 NSLog(@"提示:用户取消授权,读取失败"); } }); } else if (authorizationStatus == kABAuthorizationStatusAuthorized){ // 授权过 [self readAddressBook]; } else { dispatch_async(dispatch_get_main_queue(), ^{ // 更新界面 NSLog(@"提示:应用-通信录 设置"); }); } }
1-3)、读取并保存模型(未做)
- (void)readAddressBook { // 获取所有联系人 ABAddressBookRef addressBookRef = ABAddressBookCreate(); // 获取所有联系人 数据 CFArrayRef peoples = ABAddressBookCopyArrayOfAllPeople(addressBookRef); // 获取所有联系人 个数 CFIndex peoplesCount = ABAddressBookGetPersonCount(addressBookRef); for (int i = 0; i < peoplesCount; i++) { //获取联系人对象的引用 ABRecordRef people = CFArrayGetValueAtIndex(peoples, i); //获取当前联系人名字 NSString *firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty)); //获取当前联系人姓氏 NSString *lastName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty)); NSLog(@"--------------------------------------------------"); NSLog(@"firstName=%@, lastName=%@", firstName, lastName); //获取当前联系人中间名 NSString *middleName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNameProperty)); //获取当前联系人的名字前缀 NSString *prefix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonPrefixProperty)); //获取当前联系人的名字后缀 NSString *suffix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonSuffixProperty)); //获取当前联系人的昵称 NSString *nickName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNicknameProperty)); //获取当前联系人的名字拼音 NSString *firstNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonFirstNamePhoneticProperty)); //获取当前联系人的姓氏拼音 NSString *lastNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonLastNamePhoneticProperty)); //获取当前联系人的中间名拼音 NSString *middleNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNamePhoneticProperty)); //获取当前联系人的公司 NSString *organization=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonOrganizationProperty)); //获取当前联系人的职位 NSString *job=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonJobTitleProperty)); //获取当前联系人的部门 NSString *department=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonDepartmentProperty)); //获取当前联系人的生日 NSDate *birthday=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonBirthdayProperty)); //获取当前联系人的备注 NSString *notes=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNoteProperty)); //获取当前联系人头像图片 NSData *userImage=(__bridge NSData*)(ABPersonCopyImageData(people)); //获取kind值 CFNumberRef kindType = ABRecordCopyValue(people, kABPersonKindProperty); if (kindType == kABPersonKindOrganization) { NSLog(@"公司"); } else { // it's a person, resource, or room NSLog(@"个人"); } //获取创建当前联系人的时间 注意是NSDate NSDate *creatTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonCreationDateProperty)); //获取最近修改当前联系人的时间 NSDate *alterTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonModificationDateProperty)); //获取当前联系人的电话 数组 NSMutableArray *phoneArray = [[NSMutableArray alloc]init]; ABMultiValueRef phones = ABRecordCopyValue(people, kABPersonPhoneProperty); CFIndex phonesCount = ABMultiValueGetCount(phones); for (NSInteger j=0; j<phonesCount; j++) { //获取电话Label NSString *phoneLabel = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phones, j)); //获取該Label下的电话值 NSString *phone = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(phones, j)); NSLog(@"phone=%@", phone); [phoneArray addObject:phone]; } //获取IM多值 NSMutableArray *instantMessageArray = [[NSMutableArray alloc]init]; ABMultiValueRef instantMessages = ABRecordCopyValue(people, kABPersonInstantMessageProperty); CFIndex instantMessagesCount = ABMultiValueGetCount(instantMessages); for (int j = 1; j < instantMessagesCount; j++) { //获取IM Label NSString* instantMessageLabel = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(instantMessages, j); //获取IM 的内容 NSDictionary* instantMessageContent =(__bridge NSDictionary*)ABMultiValueCopyValueAtIndex(instantMessages, j); NSString* username = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageUsernameKey]; NSString* service = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageServiceKey]; } //获取URL多值 NSMutableArray *urlArray = [[NSMutableArray alloc]init]; ABMultiValueRef urls = ABRecordCopyValue(people, kABPersonURLProperty); CFIndex urlsCount = ABMultiValueGetCount(urls); for (int j = 0; j < urlsCount; j++) { //获取电话Label NSString * urlLabel = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(urls, j)); //获取該Label下的电话值 NSString * urlContent = (__bridge NSString*)ABMultiValueCopyValueAtIndex(urls,j); } //获取当前联系人的邮箱 注意是数组 NSMutableArray *emailArray = [[NSMutableArray alloc]init]; ABMultiValueRef emails= ABRecordCopyValue(people, kABPersonEmailProperty); CFIndex emailsCount = ABMultiValueGetCount(emails); for (NSInteger j=0; j< emailsCount; j++) { //获取email Label NSString* emailLabel = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(emails, j)); //获取email值 NSString *email = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(emails, j)); NSLog(@"email=%@", email); [emailArray addObject:email]; } //获取地址 注意是数组 NSMutableArray *addressArray = [[NSMutableArray alloc]init]; ABMultiValueRef addresss = ABRecordCopyValue(people, kABPersonAddressProperty); CFIndex addresssCount = ABMultiValueGetCount(addresss); for (int j=0; j<addresssCount; j++) { // 地址类型 NSString *addressLabel = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(addresss, j)); NSDictionary * personaddress = (__bridge NSDictionary *)(ABMultiValueCopyValueAtIndex(addresss, j)); // 获取地址 NSString* country = [personaddress valueForKey:(NSString *)kABPersonAddressCountryKey]; NSString* state = [personaddress valueForKey:(NSString *)kABPersonAddressStateKey]; NSString* city = [personaddress valueForKey:(NSString *)kABPersonAddressCityKey]; NSString* street = [personaddress valueForKey:(NSString *)kABPersonAddressStreetKey]; NSString* zip = [personaddress valueForKey:(NSString *)kABPersonAddressZIPKey]; NSString* coutntrycode = [personaddress valueForKey:(NSString *)kABPersonAddressCountryCodeKey]; //地址字符串,可以按需求格式化 NSString *adress = [NSString stringWithFormat:@"国家:%@\n省:%@\n市:%@\n街道:%@\n邮编:%@",country,state,city,street,zip]; } //获取当前联系人纪念日 NSMutableArray *dateArr = [[NSMutableArray alloc]init]; ABMultiValueRef dates= ABRecordCopyValue(people, kABPersonDateProperty); CFIndex datesCount = ABMultiValueGetCount(dates); for (NSInteger j=0; j<datesCount; j++) { //获取dates Label NSString* dateLabel = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(dates, j)); //获取纪念日日期 NSDate *date =(__bridge NSDate*)(ABMultiValueCopyValueAtIndex(dates, j)); //获取纪念日名称 NSString *str =(__bridge NSString*)(ABMultiValueCopyLabelAtIndex(dates, j)); NSDictionary *tempDic = [NSDictionary dictionaryWithObject:date forKey:str]; [dateArr addObject:tempDic]; } } }
2)、9.0以后
2-1)、头文件
#import <Contacts/Contacts.h>
2-2)、判断是否有权限
- (void)DetermineAndReadAddressBook { // 判断是否授权 CNAuthorizationStatus authorizationStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]; if (authorizationStatus == CNAuthorizationStatusNotDetermined) { CNContactStore *contactStore = [[CNContactStore alloc] init]; [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { if (granted) { // 授权成功 [self readAddressBook]; } else { // 授权失败 NSLog(@"提示:用户取消授权,读取失败"); } }]; } else if (authorizationStatus == CNAuthorizationStatusAuthorized){ // 授权过 [self readAddressBook]; } else { dispatch_async(dispatch_get_main_queue(), ^{ // 更新界面 NSLog(@"提示:应用-通信录 设置"); }); } }
2-3)、读取并保存模型(未做)
- (void)readAddressBook { // 获取指定的字段,如果这里不列出,在下面block读取,会奔溃。注意,有一个是10.0以后的。 NSArray *keysToFetch = @[CNContactNamePrefixKey, CNContactGivenNameKey, CNContactMiddleNameKey, CNContactFamilyNameKey, CNContactPreviousFamilyNameKey, CNContactNameSuffixKey, CNContactNicknameKey, CNContactOrganizationNameKey, CNContactDepartmentNameKey, CNContactJobTitleKey, CNContactPhoneticGivenNameKey, CNContactPhoneticMiddleNameKey, CNContactPhoneticFamilyNameKey, CNContactPhoneticOrganizationNameKey, // 10.0 CNContactBirthdayKey, CNContactNonGregorianBirthdayKey, CNContactNoteKey, CNContactImageDataKey, CNContactThumbnailImageDataKey, CNContactImageDataAvailableKey, CNContactTypeKey, CNContactPhoneNumbersKey, CNContactEmailAddressesKey, CNContactPostalAddressesKey, CNContactDatesKey, CNContactUrlAddressesKey, CNContactRelationsKey, CNContactSocialProfilesKey, CNContactInstantMessageAddressesKey]; CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch]; CNContactStore *contactStore = [[CNContactStore alloc] init]; [contactStore enumerateContactsWithFetchRequest:fetchRequest error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) { // 获取名字 NSString *givenName = contact.givenName; NSString *familyName = contact.familyName; NSLog(@"-------------------------------------------------------"); NSLog(@"givenName=%@, familyName=%@", givenName, familyName); // 获取电话 NSArray *phoneNumbers = contact.phoneNumbers; for (CNLabeledValue *labelValue in phoneNumbers) { NSString *label = labelValue.label; CNPhoneNumber *phoneNumber = labelValue.value; NSLog(@"label=%@, phone=%@", label, phoneNumber.stringValue); } // 获取对方IM NSArray *ims = contact.instantMessageAddresses; for (CNLabeledValue *labelValue in ims) { NSString *label = labelValue.label; CNInstantMessageAddress *adds = labelValue.value; NSLog(@"label=%@, add.username=%@,add.service=%@", label, adds.username , adds.service); } // *stop = YES; // 停止循环,相当于break; }]; }
3、参考
《iOS的通讯录开发》 --千煌89 简书
《iOS 获取通讯录的4种方式详解》 --vbirdbest CSDN