你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> IOS開發教程——通訊錄

IOS開發教程——通訊錄

編輯:IOS開發綜合

IOS開發教程——通訊錄。iOS中帶有一個Contacts應用程序來管理聯系人,但是有些時候我們希望自己的應用能夠訪問或者修改這些信息,這個時候就要用到AddressBook.framework框架。iOS中的通訊錄是存儲在數據庫中的,由於iOS的權限設計,開發人員是不允許直接訪問通訊錄數據庫的,必須依靠AddressBook提供的標准API來實現通訊錄操作。通過AddressBook.framework開發者可以從底層去操作AddressBook.framework的所有信息,但是需要注意的是這個框架是基於C語言編寫的,無法使用ARC來管理內存,開發者需要自己管理內存。下面大致介紹一下通訊錄操作中常用的類型:

ABAddressBookRef:代表通訊錄對象,通過該對象開發人員不用過多的關注通訊錄的存儲方式,可以直接以透明的方式去訪問、保存(在使用AddressBook.framework操作聯系人時,所有的增加、刪除、修改後都必須執行保存操作,類似於Core Data)等。

ABRecordRef:代表一個通用的記錄對象,可以是一條聯系人信息,也可以是一個群組,可以通過ABRecordGetRecordType()函數獲得具體類型。如果作為聯系人(事實上也經常使用它作為聯系人),那麼這個記錄記錄了一個完整的聯系人信息(姓名、性別、電話、郵件等),每條記錄都有一個唯一的ID標示這條記錄(可以通過ABRecordGetRecordID()函數獲得)。

ABPersonRef:代表聯系人信息,很少直接使用,實際開發過程中通常會使用類型為“kABPersonType”的ABRecordRef來表示聯系人(由此可見ABPersonRef其實是一種類型為“kABPersonType”的ABRecordRef)

ABGroupRef:代表群組,與ABPersonRef類似,很少直接使用ABGroupRef,而是使用類型為“kABGroupType”的ABRecordRef來表示群組,一個群組可以包含多個聯系人,一個聯系人也同樣可以多個群組。

由於通訊錄操作的關鍵是對ABRecordRef的操作,首先看一下常用的操作通訊錄記錄的方法:

ABPersonCreate():創建一個類型為“kABPersonType”的ABRecordRef。

ABRecordCopyValue():取得指定屬性的值。

ABRecordCopyCompositeName():取得聯系人(或群組)的復合信息(對於聯系人則包括:姓、名、公司等信息,對於群組則返回組名稱)。

ABRecordSetValue():設置ABRecordRef的屬性值。注意在設置ABRecordRef的值時又分為單值屬性和多值屬性:單值屬性設置只要通過ABRecordSetValue()方法指定屬性名和值即可;多值屬性則要先通過創建一個ABMutableMultiValueRef類型的變量,然後通過ABMultiValueAddValueAndLabel()方法依次添加屬性值,最後通過ABRecordSetValue()方法將ABMutableMultiValueRef類型的變量設置為記錄值。

ABRecordRemoveValue():刪除指定的屬性值。

注意:

由於聯系人訪問時(讀取、設置、刪除時)牽扯到大量聯系人屬性,可以到ABPerson.h中查詢或者直接到幫助文檔“Personal Information Properties”

通訊錄的訪問步驟一般如下:

調用ABAddressBookCreateWithOptions()方法創建通訊錄對象ABAddressBookRef。

調用ABAddressBookRequestAccessWithCompletion()方法獲得用戶授權訪問通訊錄。

調用ABAddressBookCopyArrayOfAllPeople()、ABAddressBookCopyPeopleWithName()方法查詢聯系人信息。

讀取聯系人後如果要顯示聯系人信息則可以調用ABRecord相關方法讀取相應的數據;如果要進行修改聯系人信息,則可以使用對應的方法修改ABRecord信息,然後調用ABAddressBookSave()方法提交修改;如果要刪除聯系人,則可以調用ABAddressBookRemoveRecord()方法刪除,然後調用ABAddressBookSave()提交修改操作。

也就是說如果要修改或者刪除都需要首先查詢對應的聯系人,然後修改或刪除後提交更改。如果用戶要增加一個聯系人則不用進行查詢,直接調用ABPersonCreate()方法創建一個ABRecord然後設置具體的屬性,調用ABAddressBookAddRecord方法添加即可。

下面就通過一個示例演示一下如何通過ABAddressBook.framework訪問通訊錄,這個例子中通過一個UITableViewController模擬一下通訊錄的查看、刪除、添加操作。

主控制器視圖,用於顯示聯系人,修改刪除聯系人:

KCContactViewController.h

//

// KCTableViewController.h

// AddressBook

//

// Created by Kenshin Cui on 14/04/05.

// Copyright (c) 2014年 cmjstudio. All rights reserved.

//

#import

/**

* 定義一個協議作為代理

*/

@protocol KCContactDelegate

//新增或修改聯系人

-(void)editPersonWithFirstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber;

//取消修改或新增

-(void)cancelEdit;

@end

@interface KCContactTableViewController : UITableViewController

@end

KCContactViewController.m

//

// KCTableViewController.m

// AddressBook

//

// Created by Kenshin Cui on 14/04/05.

// Copyright (c) 2014年 cmjstudio. All rights reserved.

//

#import "KCContactTableViewController.h"

#import

#import "KCAddPersonViewController.h"

@interface KCContactTableViewController ()

@property (assign,nonatomic) ABAddressBookRef addressBook;//通訊錄

@property (strong,nonatomic) NSMutableArray *allPerson;//通訊錄所有人員

@property (assign,nonatomic) int isModify;//標識是修改還是新增,通過選擇cell進行導航則認為是修改,否則視為新增

@property (assign,nonatomic) UITableViewCell *selectedCell;//當前選中的單元格

@end

@implementation KCContactTableViewController

#pragma mark - 控制器視圖

- (void)viewDidLoad {

[super viewDidLoad];

//請求訪問通訊錄並初始化數據

[self requestAddressBook];

}

//由於在整個視圖控制器周期內addressBook都駐留在內存中,所有當控制器視圖銷毀時銷毀該對象

-(void)dealloc{

if (self.addressBook!=NULL) {

CFRelease(self.addressBook);

}

}

#pragma mark - UI事件

//點擊刪除按鈕

- (IBAction)trashClick:(UIBarButtonItem *)sender {

self.tableView.editing=!self.tableView.editing;

}

#pragma mark - UITableView數據源方法

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

return 1;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return self.allPerson.count;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *identtityKey=@"myTableViewCellIdentityKey1";

UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:identtityKey];

if(cell==nil){

cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identtityKey];

}

//取得一條人員記錄

ABRecordRef recordRef=(__bridge ABRecordRef)self.allPerson[indexPath.row];

//取得記錄中得信息

NSString *firstName=(__bridge NSString *) ABRecordCopyValue(recordRef, kABPersonFirstNameProperty);//注意這裡進行了強轉,不用自己釋放資源

NSString *lastName=(__bridge NSString *)ABRecordCopyValue(recordRef, kABPersonLastNameProperty);

ABMultiValueRef phoneNumbersRef= ABRecordCopyValue(recordRef, kABPersonPhoneProperty);//獲取手機號,注意手機號是ABMultiValueRef類,有可能有多條

// NSArray *phoneNumbers=(__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneNumbersRef);//取得CFArraryRef類型的手機記錄並轉化為NSArrary

long count= ABMultiValueGetCount(phoneNumbersRef);

// for(int i=0;i // NSString *phoneLabel= (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(phoneNumbersRef, i));

// NSString *phoneNumber=(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phoneNumbersRef, i));

// NSLog(@"%@:%@",phoneLabel,phoneNumber);

// }

cell.textLabel.text=[NSString stringWithFormat:@"%@ %@",firstName,lastName];

if (count>0) {

cell.detailTextLabel.text=(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phoneNumbersRef, 0));

}

if(ABPersonHasImageData(recordRef)){//如果有照片數據

NSData *imageData= (__bridge NSData *)(ABPersonCopyImageData(recordRef));

cell.imageView.image=[UIImage imageWithData:imageData];

}else{

cell.imageView.image=[UIImage imageNamed:@"avatar"];//沒有圖片使用默認頭像

}

//使用cell的tag存儲記錄id

cell.tag=ABRecordGetRecordID(recordRef);

return cell;

}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if (editingStyle == UITableViewCellEditingStyleDelete) {

ABRecordRef recordRef=(__bridge ABRecordRef )self.allPerson[indexPath.row];

[self removePersonWithRecord:recordRef];//從通訊錄刪除

[self.allPerson removeObjectAtIndex:indexPath.row];//從數組移除

[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];//從列表刪除

} else if (editingStyle == UITableViewCellEditingStyleInsert) {

// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view

}

}

#pragma mark - UITableView代理方法

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

self.isModify=1;

self.selectedCell=[tableView cellForRowAtIndexPath:indexPath];

[self performSegueWithIdentifier:@"AddPerson" sender:self];

}

#pragma mark - Navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

if([segue.identifier isEqualToString:@"AddPerson"]){

UINavigationController *navigationController=(UINavigationController *)segue.destinationViewController;

//根據導航控制器取得添加/修改人員的控制器視圖

KCAddPersonViewController *addPersonController=(KCAddPersonViewController *)navigationController.topViewController;

addPersonController.delegate=self;

//如果是通過選擇cell進行的導航操作說明是修改,否則為添加

if (self.isModify) {

UITableViewCell *cell=self.selectedCell;

addPersonController.recordID=(ABRecordID)cell.tag;//設置

NSArray *array=[cell.textLabel.text componentsSeparatedByString:@" "];

if (array.count>0) {

addPersonController.firstNameText=[array firstObject];

}

if (array.count>1) {

addPersonController.lastNameText=[array lastObject];

}

addPersonController.workPhoneText=cell.detailTextLabel.text;

}

}

}

#pragma mark - KCContact代理方法

-(void)editPersonWithFirstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber{

if (self.isModify) {

UITableViewCell *cell=self.selectedCell;

NSIndexPath *indexPath= [self.tableView indexPathForCell:cell];

[self modifyPersonWithRecordID:(ABRecordID)cell.tag firstName:firstName lastName:lastName workNumber:workNumber];

[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];

}else{

[self addPersonWithFirstName:firstName lastName:lastName workNumber:workNumber];//通訊簿中添加信息

[self initAllPerson];//重新初始化數據

[self.tableView reloadData];

}

self.isModify=0;

}

-(void)cancelEdit{

self.isModify=0;

}

#pragma mark - 私有方法

/**

* 請求訪問通訊錄

*/

-(void)requestAddressBook{

//創建通訊錄對象

self.addressBook=ABAddressBookCreateWithOptions(NULL, NULL);

//請求訪問用戶通訊錄,注意無論成功與否block都會調用

ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error) {

if (!granted) {

NSLog(@"未獲得通訊錄訪問權限!");

}

[self initAllPerson];

});

}

/**

* 取得所有通訊錄記錄

*/

-(void)initAllPerson{

//取得通訊錄訪問授權

ABAuthorizationStatus authorization= ABAddressBookGetAuthorizationStatus();

//如果未獲得授權

if (authorization!=kABAuthorizationStatusAuthorized) {

NSLog(@"尚未獲得通訊錄訪問授權!");

return ;

}

//取得通訊錄中所有人員記錄

CFArrayRef allPeople= ABAddressBookCopyArrayOfAllPeople(self.addressBook);

self.allPerson=(__bridge NSMutableArray *)allPeople;

//釋放資源

CFRelease(allPeople);

}

/**

* 刪除指定的記錄

*

* @param recordRef 要刪除的記錄

*/

-(void)removePersonWithRecord:(ABRecordRef)recordRef{

ABAddressBookRemoveRecord(self.addressBook, recordRef, NULL);//刪除

ABAddressBookSave(self.addressBook, NULL);//刪除之後提交更改

}

/**

* 根據姓名刪除記錄

*/

-(void)removePersonWithName:(NSString *)personName{

CFStringRef personNameRef=(__bridge CFStringRef)(personName);

CFArrayRef recordsRef= ABAddressBookCopyPeopleWithName(self.addressBook, personNameRef);//根據人員姓名查找

CFIndex count= CFArrayGetCount(recordsRef);//取得記錄數

for (CFIndex i=0; i ABRecordRef recordRef=CFArrayGetValueAtIndex(recordsRef, i);//取得指定的記錄

ABAddressBookRemoveRecord(self.addressBook, recordRef, NULL);//刪除

}

ABAddressBookSave(self.addressBook, NULL);//刪除之後提交更改

CFRelease(recordsRef);

}

/**

* 添加一條記錄

*

* @param firstName 名

* @param lastName 姓

* @param iPhoneName iPhone手機號

*/

-(void)addPersonWithFirstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber{

//創建一條記錄

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(self.addressBook, recordRef, NULL);

//保存通訊錄,提交更改

ABAddressBookSave(self.addressBook, NULL);

//釋放資源

CFRelease(recordRef);

CFRelease(multiValueRef);

}

/**

* 根據RecordID修改聯系人信息

*

* @param recordID 記錄唯一ID

* @param firstName 姓

* @param lastName 名

* @param homeNumber 工作電話

*/

-(void)modifyPersonWithRecordID:(ABRecordID)recordID firstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber{

ABRecordRef recordRef=ABAddressBookGetPersonWithRecordID(self.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);

}

@end

新增或修改控制器視圖,用於顯示一個聯系人的信息或者新增一個聯系人:

KCAddPersonViewController.h

//

// KCAddPersonViewController.h

// AddressBook

//

// kABPersonFirstNameProperty

// Copyright (c) 2014年 cmjstudio. All rights reserved.

//

#import

@protocol KCContactDelegate;

@interface KCAddPersonViewController : UIViewController

@property (assign,nonatomic) int recordID;//通訊錄記錄id,如果ID不為0則代表修改否則認為是新增

@property (strong,nonatomic) NSString *firstNameText;

@property (strong,nonatomic) NSString *lastNameText;

@property (strong,nonatomic) NSString *workPhoneText;

@property (strong,nonatomic) id delegate;

@end

KCAddPersonViewController.m

//

// KCAddPersonViewController.m

// AddressBook

//

// kABPersonFirstNameProperty

// Copyright (c) 2014年 cmjstudio. All rights reserved.

//

#import "KCAddPersonViewController.h"

#import "KCContactTableViewController.h"

@interface KCAddPersonViewController ()

@property (weak, nonatomic) IBOutlet UITextField *firstName;

@property (weak, nonatomic) IBOutlet UITextField *lastName;

@property (weak, nonatomic) IBOutlet UITextField *workPhone;

@end

@implementation KCAddPersonViewController

- (void)viewDidLoad {

[super viewDidLoad];

[self setupUI];

}

#pragma mark - UI事件

- (IBAction)cancelClick:(UIBarButtonItem *)sender {

[self.delegate cancelEdit];

[self dismissViewControllerAnimated:YES completion:nil];

}

- (IBAction)doneClick:(UIBarButtonItem *)sender {

//調用代理方法

[self.delegate editPersonWithFirstName:self.firstName.text lastName:self.lastName.text workNumber:self.workPhone.text];

[self dismissViewControllerAnimated:YES completion:nil];

}

#pragma mark - 私有方法

-(void)setupUI{

if (self.recordID) {//如果ID不為0則認為是修改,此時需要初始化界面

self.firstName.text=self.firstNameText;

self.lastName.text=self.lastNameText;

self.workPhone.text=self.workPhoneText;

}

}

@end

運行效果:

AddressBook

備注:

1.上文中所指的以Ref結尾的對象事實上是該對象的指針(或引用),在C語言的框架中多數類型會以Ref結尾,這個類型本身就是一個指針,定義時不需要加“*”。

2.通常方法中包含copy、create、new、retain等關鍵字的方法創建的變量使用之後需要調用對應的release方法釋放。例如:使用ABPersonCreate();創建完ABRecordRef變量後使用CFRelease()方法釋放。

3.在與很多C語言框架交互時可以都存在Obj-C和C語言類型之間的轉化(特別是Obj-C和Core Foundation框架中的一些轉化),此時可能會用到橋接,只要在強轉之後前面加上”__bridge”即可,經過橋接轉化後的類型不需要再去手動維護內存,也就不需要使用對應的release方法釋放內存。

4.AddressBook框架中很多類型的創建、屬性設置等都是以這個類型名開發頭的方法來創建的,事實上如果大家熟悉了其他框架會發現也都是類似的,這是Apple開發中約定俗成的命名規則(特別是C語言框架)。例如:要給ABRecordRef類型的變量設置屬性則可以通過ABRecordSetValue()方法完成。

AddressBookUI

使用AddressBook.framework來操作通訊錄特點就是可以對通訊錄有更加精確的控制,但是缺點就是面對大量C語言API稍嫌麻煩,於是Apple官方提供了另一套框架供開發者使用,那就是AddressBookUI.framework。例如前面查看、新增、修改人員的界面這個框架就提供了現成的控制器視圖供開發者使用。下面是這個框架中提供的控制器視圖:

ABPersonViewController:用於查看聯系人信息(可設置編輯)。需要設置displayedPerson屬性來設置要顯示或編輯的聯系人。

ABNewPersonViewController:用於新增聯系人信息。

ABUnknownPersonViewController:用於顯示一個未知聯系人(尚未保存的聯系人)信息。需要設置displayedPerson屬性來設置要顯示的未知聯系人。

以上三個控制器視圖均繼承於UIViewController,在使用過程中必須使用一個UINavigationController進行包裝,否則只能看到視圖內容無法進行操作(例如對於ABNewPersonViewController如果不使用UINavigationController進行包裝則沒有新增和取消按鈕),同時注意包裝後的控制器視圖不需要處理具體新增、修改邏輯(增加和修改的處理邏輯對應的控制器視圖內部已經完成),但是必須處理控制器的關閉操作(調用dismissViewControllerAnimated::方法),並且可以通過代理方法獲得新增、修改的聯系人。下面看一下三個控制器視圖的代理方法:

1.ABPersonViewController的displayViewDelegate代理方法:

-(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier:此方法會在選擇了一個聯系人屬性後觸發,四個參數分別代表:使用的控制器視圖、所查看的聯系人、所選則的聯系人屬性、該屬性是否是多值屬性。

2.ABNewPersonViewController的newPersonViewDelegate代理方法:

-(void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person:點擊取消或完成後觸發,如果參數中的person為NULL說明點擊了取消,否則說明點擊了完成。無論是取消還是完成操作,此方法調用時保存操作已經進行完畢,不需要在此方法中自己保存聯系人信息。

3.ABUnkownPersonViewcontroller的unkownPersonViewDelegate代理方法:

-(void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownCardViewController didResolveToPerson:(ABRecordRef)person:保存此聯系人時調用,調用後將此聯系人返回。

-(BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier:選擇一個位置聯系人屬性之後執行,返回值代表是否執行默認的選擇操作(例如如果是手機號,默認操作會撥打此電話)

除了上面三類控制器視圖在AddressBookUI中還提供了另外一個控制器視圖ABPeoplePickerNavigationController,它與之前介紹的UIImagePickerController、MPMediaPickerController類似,只是他是用來選擇一個聯系人的。這個控制器視圖本身繼承於UINavigationController,視圖自身的“組”、“取消”按鈕操作不需要開發者來完成(例如開發者不用在點擊取消是關閉當前控制器視圖,它自身已經實現了關閉方法),當然這裡主要說一下這個控制器視圖的peoplePickerDelegate代理方法:

-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person:選擇一個聯系人後執行。此代理方法實現後代理方法“-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier”不會再執行。並且一旦實現了這個代理方法用戶只能選擇到聯系人視圖,無法查看具體聯系人的信息。

-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker:用戶點擊取消後執行。

-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier:選擇聯系人具體的屬性後執行,注意如果要執行此方法則不能實現-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person代理方法,此時如果點擊一個具體聯系人會導航到聯系人詳細信息界面,用戶點擊具體的屬性後觸發此方法。

下面就看一下上面四個控制器視圖的使用方法,在下面的程序中定義了四個按鈕,點擊不同的按鈕調用不同的控制器視圖用於演示:

//

// ViewController.m

// AddressBookUI

//

// Created by Kenshin Cui on 14/04/05.

// Copyright (c) 2014年 cmjstudio. All rights reserved.

//

#import "ViewController.h"

#import

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

}

#pragma mark - UI事件

//添加聯系人

- (IBAction)addPersonClick:(UIButton *)sender {

ABNewPersonViewController *newPersonController=[[ABNewPersonViewController alloc]init];

//設置代理

newPersonController.newPersonViewDelegate=self;

//注意ABNewPersonViewController必須包裝一層UINavigationController才能使用,否則不會出現取消和完成按鈕,無法進行保存等操作

UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:newPersonController];

[self presentViewController:navigationController animated:YES completion:nil];

}

//

- (IBAction)unknownPersonClick:(UIButton *)sender {

ABUnknownPersonViewController *unknownPersonController=[[ABUnknownPersonViewController alloc]init];

//設置未知人員

ABRecordRef recordRef=ABPersonCreate();

ABRecordSetValue(recordRef, kABPersonFirstNameProperty, @"Kenshin", NULL);

ABRecordSetValue(recordRef, kABPersonLastNameProperty, @"Cui", NULL);

ABMultiValueRef multiValueRef=ABMultiValueCreateMutable(kABStringPropertyType);

ABMultiValueAddValueAndLabel(multiValueRef, @"18500138888", kABHomeLabel, NULL);

ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);

unknownPersonController.displayedPerson=recordRef;

//設置代理

unknownPersonController.unknownPersonViewDelegate=self;

//設置其他屬性

unknownPersonController.allowsActions=YES;//顯示標准操作按鈕

unknownPersonController.allowsAddingToAddressBook=YES;//是否允許將聯系人添加到地址簿

CFRelease(multiValueRef);

CFRelease(recordRef);

//使用導航控制器包裝

UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:unknownPersonController];

[self presentViewController:navigationController animated:YES completion:nil];

}

- (IBAction)showPersonClick:(UIButton *)sender {

ABPersonViewController *personController=[[ABPersonViewController alloc]init];

//設置聯系人

ABAddressBookRef addressBook=ABAddressBookCreateWithOptions(NULL, NULL);

ABRecordRef recordRef= ABAddressBookGetPersonWithRecordID(addressBook, 1);//取得id為1的聯系人記錄

personController.displayedPerson=recordRef;

//設置代理

personController.personViewDelegate=self;

//設置其他屬性

personController.allowsActions=YES;//是否顯示發送信息、共享聯系人等按鈕

personController.allowsEditing=YES;//允許編輯

// personController.displayedProperties=@[@(kABPersonFirstNameProperty),@(kABPersonLastNameProperty)];//顯示的聯系人屬性信息,默認顯示所有信息

//使用導航控制器包裝

UINavigationController *navigationController=[[UINavigationController alloc]initWithRootViewController:personController];

[self presentViewController:navigationController animated:YES completion:nil];

}

- (IBAction)selectPersonClick:(UIButton *)sender {

ABPeoplePickerNavigationController *peoplePickerController=[[ABPeoplePickerNavigationController alloc]init];

//設置代理

peoplePickerController.peoplePickerDelegate=self;

[self presentViewController:peoplePickerController animated:YES completion:nil];

}

#pragma mark - ABNewPersonViewController代理方法

//完成新增(點擊取消和完成按鈕時調用),注意這裡不用做實際的通訊錄增加工作,此代理方法調用時已經完成新增,當保存成功的時候參數中得person會返回保存的記錄,如果點擊取消person為NULL

-(void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person{

//如果有聯系人信息

if (person) {

NSLog(@"%@ 信息保存成功.",(__bridge NSString *)(ABRecordCopyCompositeName(person)));

}else{

NSLog(@"點擊了取消.");

}

//關閉模態視圖窗口

[self dismissViewControllerAnimated:YES completion:nil];

}

#pragma mark - ABUnknownPersonViewController代理方法

//保存未知聯系人時觸發

-(void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownCardViewController didResolveToPerson:(ABRecordRef)person{

if (person) {

NSLog(@"%@ 信息保存成功!",(__bridge NSString *)(ABRecordCopyCompositeName(person)));

}

[self dismissViewControllerAnimated:YES completion:nil];

}

//選擇一個人員屬性後觸發,返回值YES表示觸發默認行為操作,否則執行代理中自定義的操作

-(BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{

if (person) {

NSLog(@"選擇了屬性:%i,值:%@.",property,(__bridge NSString *)ABRecordCopyValue(person, property));

}

return NO;

}

#pragma mark - ABPersonViewController代理方法

//選擇一個人員屬性後觸發,返回值YES表示觸發默認行為操作,否則執行代理中自定義的操作

-(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{

if (person) {

NSLog(@"選擇了屬性:%i,值:%@.",property,(__bridge NSString *)ABRecordCopyValue(person, property));

}

return NO;

}

#pragma mark - ABPeoplePickerNavigationController代理方法

//選擇一個聯系人後,注意這個代理方法實現後屬性選擇的方法將不會再調用

-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person{

if (person) {

NSLog(@"選擇了%@.",(__bridge NSString *)(ABRecordCopyCompositeName(person)));

}

}

//選擇屬性之後,注意如果上面的代理方法實現後此方法不會被調用

//-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{

// if (person && property) {

// NSLog(@"選擇了屬性:%i,值:%@.",property,(__bridge NSString *)ABRecordCopyValue(person, property));

// }

//}

//點擊取消按鈕

-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{

NSLog(@"取消選擇.");

}

@end

運行效果:

ABPersonViewController ABNewPersonViewController

ABUnkownPersonViewController ABPeoplePickerNaviagationController

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved