使用到的系統框架AddressBook,AddressBookUI;IOS中的通信錄是存儲在數據庫中的,開發人員不能直接訪問通信錄數據庫,必須依靠AddressBook提供的API來實現通信錄操做,經過AddressBook.FrameWork能夠操做通信錄信息,可是AddressBook框架是基於C語言編寫的,沒法使用ARC管理內存,須要本身手動管理。ios
AddressBook框架的經常使用類型:數據庫
ABAddressBookRef:表明通信錄對象。經過該對象,能夠直接訪問和保存通信錄信息。數組
ABRecordRef:表明一個通用的記錄對象,經常使用。做爲聯繫人,該對象完整記錄了聯繫人信息(姓名,性別,電話,郵件),每一個ABRecordRef 都有一條惟一的ID表示,(能夠經過ABRecordGetRecordID())得到。app
ABPersonRef:表明聯繫人信息,不多使用,實際開發中常使用kABPersonType 的ABPersonRef 來表示聯繫人;框架
ABGrounpRef:表明羣組。ide
對通信錄的操做,關鍵是對ABRecordRef的操做,經常使用方法以下:.net
ABPersonCreate():建立一個類型爲「kABPersonType」的ABRecordRef;代理
ABRecordCopyValue():取得聯繫人屬性:官方文檔的屬性:orm
因爲聯繫人訪問時(讀取、設置、刪除時)牽扯到大量聯繫人屬性,能夠到ABPerson.h中查詢或者直接到幫助文檔「Personal Information Properties」對象
ABRecordSetValue(): 設置ABRecordRef的屬性值。分爲單屬性和多屬性,單屬性使用ABRecordSetValue();多屬性經過建立一個ABMutableMultiValueRef類型的變量,而後經過ABMultiValueAddValueAndLabel ()方法依次添加屬性值,最後經過ABRecordRefSetValue ()方法 將ABMutableMultiValueRef類型的變量設置爲記錄值。
ABRecordRmoveValue ():刪除指定的屬性值。
注意: 取出的對象爲CF對象,編譯器沒法自動釋放,能夠經過 bridge-casts 轉換成NSObject對象,例如 NSString*firstname=(__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);有關bridge-casts 能夠參考這篇文章http://blog.csdn.net/chengwuli125/article/details/25497051 。
建議使用 CFBridgingRelease(),從 Core Foundation 傳遞全部權給 Objective-C;
使用 CFBridgingRetain(),從 Objective-C 傳遞全部權給 Core Foundation;這樣就不用手動釋放CF對象。
以上爲AddressBook框架對象及方法的介紹,接下來就是讀取聯繫人,項目中用到的是最簡單的調用系統的AddressBookUI框架。
1、 使用ABPeoplePickerNavigationController 侷限:只能選擇一個聯繫人,且不能定製頁面。優勢:方便快捷,視圖自己繼承於UINavigationCotroller 不須要使用UInavigationcontroller 封裝。
做爲模態視圖推出便可。
ABPeoplePickerNavigationController*ppvc=[[ABPeoplePickerNavigationController alloc]init];
ppvc.peoplePickerDelegate=self;//設置代理
[self.navigationController presentViewController:ppvc animated:YES completion:nil];
方法:代理ABPeoplePickerNavigationControllerDelegate;
// Called after a person has been selected by the user.
iOS8方法,選中聯繫人後的操做,
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person NS_AVAILABLE_IOS(8_0);
能夠根據本身須要對person 屬性進行處理。
取姓名:NSString*firstname=(__bridgeNSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
取電話:ABMultiValueRef phones=ABRecordCopyValue(person, kABPersonPhoneProperty);
for(int i=0;i<ABMultiValueGetCount(phones);i++)
{
NSString*phone=(__bridge NSString *)ABMultiValueCopyValueAtIndex(phones, i);
[_phoneNumber addObject:phone];
}
電話取出後爲一數組,可能不止一個。
// Called after a property has been selected by the user.
iOS8 選中聯繫人屬性後的方法,若是上一個方法實現 這個方法不會調用。
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier NS_AVAILABLE_IOS(8_0);
// Called after the user has pressed cancel.
點擊取消後的操做
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;
注意:選擇聯繫人或點擊取消後 都要
[self dismissViewControllerAnimated:YES completion:nil];
如下爲之前的方法,在iOS8 上選取聯繫人後會進入聯繫人詳細頁面,不會讀取聯繫人信息,慎用。
// Deprecated, use predicateForSelectionOfPerson and/or -peoplePickerNavigationController:didSelectPerson: instead.
-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person NS_DEPRECATED_IOS(2_0, 8_0);
// , use predicateForSelectionOfProperty and/or -peoplePickerNavigationController:didSelectPerson:property:identifier: instead.
-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier NS_DEPRECATED_IOS(2_0, 8_0);
2、addressBookUI 還提供ABPersonViewController :用於查看聯繫人信息(須要設置displayedPerson屬性 來顯示或須要編輯的聯繫人);
ABNewPersonViewController :用於新增聯繫人。
ABUnknownPersonViewController :用於顯示未知聯繫人。
以上均繼承於UIViewController 在使用過程當中必須使用一個UINavigationController 進行封裝,不然只能看到視圖,沒法操做。封裝後沒必要處理具體新增,修改聯繫人的邏輯,但必須處理關閉操做即調用 dismissViewControllerAnimated的方法。
更多時候開發中會本身定製通信錄,即經過addressBook框架進行開發。
開發步驟:一、建立通信錄對象ABAddressBookRef ABAddressBookCreateWithOpio();
二、得到用戶受權訪問通信錄 ABAddressBookRrequestAccessWithCompletion();
三、查詢聯繫人信息 ABAddressBookCopyArrayOfAllPeople(),ABAddressBookCopyPeopleWithName();
四、讀取聯繫人後若是要顯示聯繫人信息則能夠調用ABRecord相關方法讀取相應的數據;若是要進行修改聯繫人信息,則可使用對應的方法修改ABRecord信息,而後調用ABAddressBookSave()方法提交修改;若是要刪除聯繫人,則能夠調用ABAddressBookRemoveRecord()方法刪除,而後調用ABAddressBookSave()提交修改操做。
五、若是要修改或者刪除都須要首先查詢對應的聯繫人,而後修改或刪除後提交更改。若是用戶要增長一個聯繫人則不用進行查詢,直接調用ABPersonCreate()方法建立一個ABRecord而後設置具體的屬性,調用ABAddressBookAddRecord方法添加便可。
讀取所有聯繫人信息:
一、ABAddressBookRef addressBook=ABAddressBookCreateWithOptions(nil, nil);
CFArrayRef allperson =ABAddressBookCopyArrayOfAllPeople(addressBook);
NSArray *array=CFBridgingRelease(allperson);
新建聯繫人:
//建立一條記錄
ABRecordRef recordRef= ABPersonCreate();
ABRecordSetValue(recordRef, kABPersonFirstNameProperty, (__bridge CFTypeRef)(firstName), NULL);//添加名
ABRecordSetValue(recordRef, kABPersonLastNameProperty, (__bridge CFTypeRef)(lastName), NULL);//添加姓
ABMutableMultiValueRef multiValueRef =ABMultiValueCreateMutable(kABStringPropertyType);//添加設置多值屬性
ABMultiValueAddValueAndLabel(multiValueRef, (__bridge CFStringRef)(workNumber), kABWorkLabel, NULL);//添加工做電話
ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);
//添加記錄
ABAddressBookAddRecord(addressBook, recordRef, NULL);
//保存通信錄,提交更改
ABAddressBookSave(addressBook, NULL);
//釋放資源
CFRelease(recordRef);
CFRelease(multiValueRef);
三、根據姓名刪除聯繫人
CFStringRef personNameRef=(__bridge CFStringRef)(personName);
CFArrayRef recordsRef= ABAddressBookCopyPeopleWithName(addressBook, personNameRef);//根據人員姓名查找
CFIndex count= CFArrayGetCount(recordsRef);//取得記錄數
for (CFIndex i=0; i<count; ++i) {
ABRecordRef recordRef=CFArrayGetValueAtIndex(recordsRef, i);//取得指定的記錄
ABAddressBookRemoveRecord(self.addressBook, recordRef, NULL);//刪除
}
ABAddressBookSave(self.addressBook, NULL);//刪除以後提交更改
CFRelease(recordsRef);// 釋放資源
四、修改聯繫人信息
ABRecordRef recordRef=ABAddressBookGetPersonWithRecordID(addressBook,recordID);
ABRecordSetValue(recordRef, kABPersonFirstNameProperty, (__bridge CFTypeRef)(firstName), NULL);//添加名
ABRecordSetValue(recordRef, kABPersonLastNameProperty, (__bridge CFTypeRef)(lastName), NULL);//添加姓
ABMutableMultiValueRef multiValueRef =ABMultiValueCreateMutable(kABStringPropertyType);
ABMultiValueAddValueAndLabel(multiValueRef, (__bridge CFStringRef)(workNumber), kABWorkLabel, NULL);
ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);
//保存記錄,提交更改
ABAddressBookSave(self.addressBook, NULL);
//釋放資源
CFRelease(multiValueRef);