標籤:
這篇文章主要介紹在iOS8.0和iOS9.0有介面和無介面 擷取通訊錄資訊的方法.下面我們逐個介紹 首先我們要明確 無論是 iOS8.0和iOS9.0在有介面的情況下都不需要授權
1.iOS8.0 有介面的操作 需要匯入 AddressBookUI 靜態庫 遵循 ABPeoplePickerNavigationControllerDelegate協議
需要注意的是我們在不用橋接的情況下要注意記憶體泄露問題
#import "ViewController.h"
#import <AddressBookUI/AddressBookUI.h>
@interface ViewController () <ABPeoplePickerNavigationControllerDelegate>
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//建立控制器
//彈出控制器
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc]init];
//設定代理
picker.peoplePickerDelegate = self;
//展示介面
[self presentViewController:picker animated:YES completion:nil];
}
//選擇中 一個人的資訊就會調用
//參數1 控制器 參數2 選擇的person的資訊
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
//目標: 擷取連絡人資訊
//coreFountion
//指標 Record 記錄 資料庫 欄位 列 記錄 行
//需求 : name 電話號碼
//C語言API特徵 實現任何功能都是 調用一個函數 參數 傳回值 輸入和輸出
// name
CFStringRef strfirst = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef strlast = ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *strF = (__bridge_transfer NSString *)(strfirst);
NSString *strL = (__bridge_transfer NSString *)(strlast);
NSLog(@"%@ %@",strF,strL);
//電話號碼 ABMultiValueRef 封裝一個儲存了很多電話的一個類型
ABMultiValueRef multiValues = ABRecordCopyValue(person, kABPersonPhoneProperty);
//函數 來做
CFIndex index = ABMultiValueGetCount(multiValues);
for (CFIndex i = 0; i < index; i++) {
CFStringRef strPhone = ABMultiValueCopyValueAtIndex(multiValues, i);
NSString *phoneStr = (__bridge_transfer NSString *)(strPhone);
NSLog(@"%@",phoneStr);
}
if (multiValues != NULL) {
CFRelease(multiValues);
}
//記憶體 靜態分析工具
//C語言 API CoreFoundation create copy 等 擷取 的對象都需要釋放 -> CFRelease
//橋接
//__bridge 預設橋接
//__bridge_transfer 橋接 coreF -> ocF 轉讓對象的所有權
//__bridge_retained 橋接 ocF -> coreF 轉讓對象的所有權
}
/*備份*/ 在沒有使用橋接的情況下注意記憶體泄露問題
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
//目標: 擷取連絡人資訊
//coreFountion
//指標 Record 記錄 資料庫 欄位 列 記錄 行
//需求 : name 電話號碼
//C語言API特徵 實現任何功能都是 調用一個函數 參數 傳回值 輸入和輸出
// name
CFStringRef strfirst = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef strlast = ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *strF = (__bridge NSString *)(strfirst);
NSString *strL = (__bridge NSString *)(strlast);
NSLog(@"%@ %@",strF,strL);
if (strfirst != NULL) {
CFRelease(strfirst);
}
if (strlast != NULL)
{
CFRelease(strlast);
}
//電話號碼 ABMultiValueRef 封裝一個儲存了很多電話的一個類型
ABMultiValueRef multiValues = ABRecordCopyValue(person, kABPersonPhoneProperty);
//函數 來做
CFIndex index = ABMultiValueGetCount(multiValues);
for (CFIndex i = 0; i < index; i++) {
CFStringRef strPhone = ABMultiValueCopyValueAtIndex(multiValues, i);
NSString *phoneStr = (__bridge_transfer NSString *)(strPhone);
NSLog(@"%@",phoneStr);
if (strPhone != NULL) {
CFRelease(strPhone);
}
}
if (multiValues != NULL) {
CFRelease(multiValues);
}
//記憶體 靜態分析工具
//C語言 API CoreFoundation create copy 等 擷取 的對象都需要釋放 -> CFRelease
//橋接
//__bridge 預設橋接
//__bridge_transfer 橋接 coreF -> ocF 轉讓對象的所有權
//__bridge_retained 橋接 ocF -> coreF 轉讓對象的所有權
}
//選擇中 一個人的資訊就會調用 必須是選擇屬性 才會調用
//注意點 如果實現 上面 peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person 當前方法不執行 介面不顯示
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
NSLog(@"property %zd",property);
}
//點擊取消了 就會調用
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
NSLog(@"peoplePickerNavigationControllerDidCancel");
}
2.iOS8.0 無介面的操作 需要匯入 AddressBook 靜態庫 需要授權
#import "ViewController.h"
#import <AddressBook/AddressBook.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//擷取使用者的授權 舊的 知識
/*
kABAuthorizationStatusNotDetermined = 0, // deprecated, use CNAuthorizationStatusNotDetermined
kABAuthorizationStatusRestricted, // deprecated, use CNAuthorizationStatusRestricted
kABAuthorizationStatusDenied, // deprecated, use CNAuthorizationStatusDenied
kABAuthorizationStatusAuthorized // 已經授權
*/
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusNotDetermined) {
//參數1 通訊錄對象 參數2block 回調
ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
//申請授權
ABAddressBookRequestAccessWithCompletion(book, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(@"授權成功!");
}else{
NSLog(@"授權失敗!");
}
});
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//擷取連絡人 資訊
//name
ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
CFArrayRef allpeople = ABAddressBookCopyArrayOfAllPeople(book);
CFIndex count = CFArrayGetCount(allpeople);
for (CFIndex i = 0; i <count ; i++) {
ABRecordRef record = CFArrayGetValueAtIndex(allpeople, i);
CFStringRef strFirst = ABRecordCopyValue(record, kABPersonFirstNameProperty);
NSString *str = (__bridge_transfer NSString *)strFirst;
NSLog(@"%@",str);
//電話號碼
ABMultiValueRef multivalue = ABRecordCopyValue(record, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multivalue); i++) {
CFStringRef phoneStr = ABMultiValueCopyValueAtIndex(multivalue, i);
NSString *phone = (__bridge_transfer NSString *)(phoneStr);
NSLog(@"%@",phone);
}
}
}
3.iOS9.0 有介面的操作 需要匯入 ContactsUI 靜態庫
#import "ViewController.h"
#import <ContactsUI/ContactsUI.h>
@interface ViewController ()<CNContactPickerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//不需要授權
//1.建立通訊錄控制器
CNContactPickerViewController *picker = [[CNContactPickerViewController alloc]init];
//2.設定代理 拿到資料本身
picker.delegate = self;
//3.展示
[self presentViewController:picker animated:YES completion:nil];
}
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker;
{
NSLog(@"contactPickerDidCancel");
}
//選擇一個連絡人資訊
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact;
{
NSLog(@"didSelectContact");
//NSLog(@"%@",contact.givenName);
NSArray *allArray = contact.phoneNumbers;
for (CNLabeledValue * labeledValue in allArray) {
CNPhoneNumber *num = labeledValue.value;
NSLog(@"num = %@",num.stringValue);
NSLog(@"===%@ ===%@",labeledValue.value,labeledValue.label);
}
}
//選擇一個連絡人屬性 具體資訊
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;
{
NSLog(@"didSelectContactProperty");
}
4.iOS9.0 無介面的操作 需要匯入 Contacts 靜態庫 需要授權
#import "ViewController.h"
#import <Contacts/Contacts.h>
@interface ViewController ()
@property (nonatomic, strong) CNContactStore *store;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//授權
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
//如果沒有授權過需要請求使用者的授權
CNContactStore *store = [[CNContactStore alloc]init];
self.store = store;
if (status == CNAuthorizationStatusNotDetermined) {
//請求授權
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@"授權成功!");
}else{
NSLog(@"授權失敗!");
}
}];
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//name phone
CNContactFetchRequest *request = [[CNContactFetchRequest alloc]initWithKeysToFetch:@[CNContactGivenNameKey,CNContactPhoneNumbersKey]];
//參數1 封裝查詢請求
[self.store enumerateContactsWithFetchRequest: request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
//返回的資料 CNContact
NSLog(@"%@",contact.givenName);
NSLog(@"%@",contact.phoneNumbers);
}];
}
擷取通訊錄資訊在iOS8.0和9.0的區別