標籤:
使用到的系統架構AddressBook,AddressBookUI;IOS中的通訊錄是儲存在資料庫中的,開發人員不能直接存取通訊錄資料庫,必須依靠AddressBook提供的API來實現通訊錄操作,通過AddressBook.FrameWork可以操作通訊錄資訊,但是AddressBook架構是基於C語言編寫的,無法使用ARC管理記憶體,需要自己手動管理。
AddressBook架構的常用類型:
ABAddressBookRef:代表通訊錄對象。通過該對象,可以直接存取和儲存通訊錄資訊。
ABRecordRef:代表一個通用的記錄對象,常用。作為連絡人,該對象完整記錄了連絡人資訊(姓名,性別,電話,郵件),每個ABRecordRef 都有一條唯一的ID表示,(可以通過ABRecordGetRecordID())獲得。
ABPersonRef:代表連絡人資訊,很少使用,實際開發中常使用kABPersonType 的ABPersonRef 來表示連絡人;
ABGrounpRef:代表群組。
對通訊錄的操作,關鍵是對ABRecordRef的操作,常用方法如下:
ABPersonCreate():建立一個類型為“kABPersonType”的ABRecordRef;
ABRecordCopyValue():取得連絡人屬性:官方文檔的屬性:
由於連絡人訪問時(讀取、設定、刪除時)牽扯到大量連絡人屬性,可以到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架構。
一、 使用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);
二、addressBookUI 還提供ABPersonViewController :用於查看連絡人資訊(需要設定displayedPerson屬性 來顯示或需要編輯的連絡人);
ABNewPersonViewController :用於新增連絡人。
ABUnknownPersonViewController :用於顯示未知連絡人。
以上均繼承於UIViewController 在使用過程中必須使用一個UINavigationController 進行封裝,否則只能看到視圖,無法操作。封裝後不必處理具體新增,修改連絡人的邏輯,但必須處理關閉操作即調用 dismissViewControllerAnimated的方法。
更多時候開發中會自己定製通訊錄,即通過addressBook架構進行開發。
開發步驟:1、建立通訊錄對象ABAddressBookRef ABAddressBookCreateWithOpio();
2、獲得使用者授權訪問通訊錄 ABAddressBookRrequestAccessWithCompletion();
3、查詢連絡人資訊 ABAddressBookCopyArrayOfAllPeople(),ABAddressBookCopyPeopleWithName();
4、讀取連絡人後如果要顯示連絡人資訊則可以調用ABRecord相關方法讀取相應的資料;如果要進行修改連絡人資訊,則可以使用對應的方法修改ABRecord資訊,然後調用ABAddressBookSave()方法提交修改;如果要刪除連絡人,則可以調用ABAddressBookRemoveRecord()方法刪除,然後調用ABAddressBookSave()提交修改操作。
5、如果要修改或者刪除都需要首先查詢對應的連絡人,然後修改或刪除後提交更改。如果使用者要增加一個連絡人則不用進行查詢,直接調用ABPersonCreate()方法建立一個ABRecord然後設定具體的屬性,調用ABAddressBookAddRecord方法添加即可。
讀取全部連絡人資訊:
1、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);
3、根據姓名刪除連絡人
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);// 釋放資源
4、修改連絡人資訊
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);
iOS 通訊錄開發 AddressBook AddressBookUI架構的使用