iOS 9.0之前
- (void)fetchAddressBookBeforeIOS9{
ABAddressBookRef addressBook = ABAddressBookCreate();
//首次訪問(wèn)需用戶(hù)授權(quán)
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {//首次訪問(wèn)通訊錄
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (!error) {
if (granted) {//允許
NSLog(@"已授權(quán)訪問(wèn)通訊錄");
NSArray *contacts = [self fetchContactWithAddressBook:addressBook];
dispatch_async(dispatch_get_main_queue(), ^{
//----------------主線程 更新 UI-----------------
NSLog(@"contacts:%@", contacts);
});
}else{//拒絕
NSLog(@"拒絕訪問(wèn)通訊錄");
}
}else{
NSLog(@"發(fā)生錯(cuò)誤!");
}
});
}else{//非首次訪問(wèn)通訊錄
NSArray *contacts = [self fetchContactWithAddressBook:addressBook];
dispatch_async(dispatch_get_main_queue(), ^{
//----------------主線程 更新 UI-----------------
NSLog(@"contacts:%@", contacts);
});
}
}
- (NSMutableArray *)fetchContactWithAddressBook:(ABAddressBookRef)addressBook{
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {////有權(quán)限訪問(wèn)
//獲取聯(lián)系人數(shù)組
NSArray *array = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSMutableArray *contacts = [NSMutableArray array];
for (int i = 0; i < array.count; i++) {
//獲取聯(lián)系人
ABRecordRef people = CFArrayGetValueAtIndex((__bridge ABRecordRef)array, i);
//獲取聯(lián)系人詳細(xì)信息,如:姓名,電話(huà),住址等信息
NSString *firstName = (__bridge NSString *)ABRecordCopyValue(people, kABPersonFirstNameProperty);
NSString *lastName = (__bridge NSString *)ABRecordCopyValue(people, kABPersonLastNameProperty);
ABMutableMultiValueRef *phoneNumRef = ABRecordCopyValue(people, kABPersonPhoneProperty);
NSString *phoneNumber = ((__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneNumRef)).lastObject;
[contacts addObject:@{@"name": [firstName stringByAppendingString:lastName], @"phoneNumber": phoneNumber}];
}
return contacts;
}else{//無(wú)權(quán)限訪問(wèn)
NSLog(@"無(wú)權(quán)限訪問(wèn)通訊錄");
return nil;
}
}
iOS 9.0之后(兩種方式)
一:通過(guò)代碼就可以獲取所有通訊錄信息(需要用戶(hù)授權(quán))

image.png
獲取用戶(hù)授權(quán)
申請(qǐng)使用通訊錄,在無(wú)權(quán)限時(shí)提示用戶(hù)打開(kāi)權(quán)限
導(dǎo)入
#import <Contacts/Contacts.h>
- (IBAction)getMailListAction:(id)sender {
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusNotDetermined) {
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError* _Nullable error) {
if (error) {
//無(wú)權(quán)限
[self showAlertViewAboutNotAuthorAccessContact];
} else {
//有權(quán)限
[self openContact];
}
}];
} else if(status == CNAuthorizationStatusRestricted) {
//無(wú)權(quán)限
[self showAlertViewAboutNotAuthorAccessContact];
} else if (status == CNAuthorizationStatusDenied) {
//無(wú)權(quán)限
[self showAlertViewAboutNotAuthorAccessContact];
} else if (status == CNAuthorizationStatusAuthorized) {
//有權(quán)限
[self openContact];
}
}
- (void)showAlertViewAboutNotAuthorAccessContact{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"請(qǐng)授權(quán)通訊錄權(quán)限" message:@"請(qǐng)?jiān)趇Phone的\"設(shè)置-隱私-通訊錄\"選項(xiàng)中,允許花解解訪問(wèn)你的通訊錄" preferredStyle: UIAlertControllerStyleAlert];
UIAlertAction *OKAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:OKAction];
[self presentViewController:alertController animated:YES completion:nil];
}
// 獲取所有聯(lián)系人信息
- (void)openContact{
NSArray *keysToFetch = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch];
CNContactStore *contactStore = [[CNContactStore alloc] init];
[contactStore enumerateContactsWithFetchRequest:fetchRequest error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
NSString * firstName = contact.familyName;
NSString * lastName = contact.givenName;
//電話(huà)
NSArray * phoneNums = contact.phoneNumbers;
CNLabeledValue *labelValue = phoneNums.firstObject;
NSString *phoneValue = [labelValue.value stringValue];
NSLog(@"姓名:%@%@ 電話(huà):%@", firstName, lastName, phoneValue);
}];
}
二:打開(kāi)通訊錄選擇界面,單選或者多選聯(lián)系人,以獲取信息(無(wú)需用戶(hù)授權(quán))
- 打開(kāi)通訊錄界面
#import <ContactsUI/ContactsUI.h>
#import <Contacts/Contacts.h>
@interface ViewController () <CNContactPickerDelegate>
@end
@implementation ViewController {
CNContactPickerViewController * _peoplePickVC;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)openMailListAction:(id)sender {
_peoplePickVC = [[CNContactPickerViewController alloc] init];
_peoplePickVC.delegate = self;
[self showViewController:_peoplePickVC sender:nil];
}
注意 CNContactPickerViewController 對(duì)象需要定義為全局變量。
- 獲取單個(gè)聯(lián)系人信息
// 獲取指定聯(lián)系人 里面只log了第一個(gè)電話(huà)號(hào)碼
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact {
//姓名
NSString * firstName = contact.familyName;
NSString * lastName = contact.givenName;
//電話(huà)
NSArray * phoneNums = contact.phoneNumbers;
CNLabeledValue *labelValue = phoneNums.firstObject;
NSString *phoneValue = [labelValue.value stringValue];
NSLog(@"姓名:%@%@ 電話(huà):%@", firstName, lastName, phoneValue);
}
- 獲取單個(gè)聯(lián)系人指定電話(huà)
// 獲取指定電話(huà)
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty {
//姓名
NSString * firstName = contactProperty.contact.familyName;
NSString * lastName = contactProperty.contact.givenName;
//電話(huà)
NSString * phoneNum = [contactProperty.value stringValue];
NSLog(@"姓名:%@%@ 電話(huà):%@", firstName, lastName, phoneNum);
}
- 獲取多個(gè)聯(lián)系人信息
//獲取多個(gè)聯(lián)系人 里面只log了每個(gè)聯(lián)系人第一個(gè)電話(huà)號(hào)碼
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray<CNContact *> *)contacts {
//遍歷
for (CNContact * contact in contacts) {
//姓名
NSString * firstName = contact.familyName;
NSString * lastName = contact.givenName;
//電話(huà)
NSArray * phoneNums = contact.phoneNumbers;
CNLabeledValue *labelValue = phoneNums.firstObject;
NSString *phoneValue = [labelValue.value stringValue];
NSLog(@"姓名:%@%@ 電話(huà):%@", firstName, lastName, phoneValue);
}
}
- 只可實(shí)現(xiàn)一個(gè)代理方法,同時(shí)實(shí)現(xiàn)多個(gè)代理方法只會(huì)生效一個(gè),導(dǎo)致彈出的聯(lián)系人選擇頁(yè)面不是你想要的效果。