iOS 通信錄開發 AddressBook AddressBookUI框架的使用

使用到的系統框架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);

相關文章
相關標籤/搜索