您的位置:首页 > 产品设计 > UI/UE

IOS进阶 AddressBook.framework和AddressBookUI.framework访问通讯录

2016-06-20 14:29 489 查看
转载:http://blog.csdn.net/zhibudefeng/article/details/7677136

通讯录中联系人相关的应用iPhone提供了两个框架:AddressBook.framework和AddressBookUI.framework,使用这两个框架我们可以在程序中访问并显示iPhone数据库中的联系人信息。

[objc] view
plain copy

 





ABAddressBookRef addressBook = nil;  

              

            addressBook = ABAddressBookCreateWithOptions(NULL, NULL);  

            //等待同意后向下执行  

            dispatch_semaphore_t sema = dispatch_semaphore_create(0);  

            ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)  

                                                     {  

                                                         dispatch_semaphore_signal(sema);  

                                                     });  

            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);  


[objc] view
plain copy

 





//获取本地通讯录数据库  

  ABRecordRef moi=NULL;//联系人  

  ABRecordRef annkey=ABPersonCreate();//创建联系人  

  //设置联系人的值  

  ABRecordSetValue(annkey,kABPersonFirstNameProperty,@"annkey",NULL);  

  ABRecordSetValue(annkey,kABPersonLastNameProperty,@"hu",NULL);  

  //创建多值属性  

  ABMutableMultiValueRef addr=ABMultiValueCreateMutable(kABStringPropertyType);  

  //增加属性名和属性值,属性名为kABHomeLabel  

  ABMultiValueAddValueAndLabel(addr,@"annkey@qq.con",kABHomeLabel,NULL);  

  //设置联系人的多值邮箱属性  

  ABRecordSetValue(annkey,kABPersonEmailProperty, addr,NULL);  

  ABAddressBookAddRecord(adbk, annkey,NULL);//增加联系人  

  ABAddressBookSave(adbk,NULL);//保存联系人  

  CFRelease(addr);  

  CFRelease(annkey);//,即使是在arc机制里,c对象仍需手动释放  

  CFArrayRef sams=ABAddressBookCopyPeopleWithName(adbk, (CFStringRef)@"hu");//联系人数组,可能存在多个同名的联系人,需要通过其他属性来判断具体是哪个  

  for (CFIndex ix=0; ix  

  // 从联系人数组多个sam中读取  

  ABRecordRef sam=CFArrayGetValueAtIndex(sams, ix);  

  // 获取联系人的名属性  

  CFStringRef last=ABRecordCopyValue(sam,kABPersonLastNameProperty);  

  NSLog(@" is find %@",last);  

  //找到符合条件的联系人  

  if (last&&CFStringCompare(last, (CFStringRef)@"annkey",0)==0) {  

  moi=sam;  

  }  

  if (last) {  

  //必须要判断cf对象是否为空,只有不是null才可被释放,如果不判断会报错。  

  CFRelease(last); //c对象需手动释放  

  }  

  }  

  if (NULL==moi) {  

  //此处通讯录肯定不为空,数据库是存在的  

  CFRelease(sams);  

  CFRelease(adbk);//c对象需手动释放  

  return;  

  }  

  //获取联系人的邮件属性,初始化为多值  

  ABMultiValueRef emails=ABRecordCopyValue(moi,kABPersonEmailProperty);  

  if (NULL==emails) {  

  NSLog(@"emails is null");  

  }  

  for (CFIndex ix=0; ix  

  //联系人的属性名和属性值  

  CFStringRef labe1=ABMultiValueCopyLabelAtIndex(emails, ix);  

  CFStringRef value=ABMultiValueCopyValueAtIndex(emails, ix);  

  NSLog(@"i have a %@ address I%@",labe1,value);  

  CFRelease(labe1);  

  CFRelease(value);  

  }  

  NSLog(@"emails is null2");  

  CFRelease(emails);  

  CFRelease(sams);  

  CFRelease(adbk);  


添加地址簿框架后,我们还需要在工程中添加相应的头文件:

#import <AddressBook/AddressBook.h>

#import <AddressBookUI/AddressBookUI.h>

1.AddressBookUI显示部分

AddressBookUI中提供了和联系人显示信息相关的一些Controller,有四个:

ABPeoplePickerNavigationController:显示整个通讯录并可以选择一个联系人的信息

ABPersonViewController:显示一个具体联系人的信息

ABNewPersonViewController:增加一个新的联系人

ABUnknownPersonViewController:完善一个联系人的信息

由于其中最主要的是ABPeoplePickerNavigationController,因此就具体的介绍一下通过程序显示整个通讯录并且可以选择其中某个联系人信息的步骤。

(a)创建并初始化一个ABPeoplePickerNavigationController对象

(b)设置其代理(delegate)

(c)用presentModalViewController:animated:这个方法进行显示整个通讯录页面

例子:


- (IBAction)showPicker:(id)sender {  

    ABPeoplePickerNavigationController *picker =
 

    [[ABPeoplePickerNavigationController alloc] init];  

    picker.peoplePickerDelegate = self;
 

    [self presentModalViewController:picker animated:YES];  

   [picker release];  



ABPeoplePickerNavigationControllerDelegate的方法介绍

(1)


peoplePickerNavigationControllerDidCancel: 

当用户选择取消时调用这个方法,可以在这个方法里取消整个通讯录页面的显示。

(2)


peoplePickerNavigationController:shouldContinueAfterSelectingPerson:  

当用户选择了通讯录中某一个联系人时调用这个方法,可以在这里获取联系人的信息。如果希望可以继续显示这个联系人更具体的信息,则return YES。否则取消整个通讯录页面的显示并return NO。

(3)


eoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier:  

如果上一个方法返回的是YES,则会显示某一个联系人信息,如果选择了联系人的某一项纪录,就会调用这个方法,可以通过点击选择联系人的某一项信息。如果希望可以对选择的某一项纪录进行进一步操作,比如直接拨打电话或调用邮箱发送邮件,则return YES。否则取消整个通讯录页面的显示并return NO。

例子:


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

// assigning control back to the main controller  

[picker dismissModalViewControllerAnimated:YES];  

}  

- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker 

shouldContinueAfterSelectingPerson:(ABRecordRef)person {  

//获取联系人姓名  

name.text = (NSString*)ABRecordCopyCompositeName(person);
 

//获取联系人电话  

ABMutableMultiValueRef phoneMulti = ABRecordCopyValue(person, kABPersonPhoneProperty);
 

NSMutableArray *phones = [[NSMutableArray alloc] init];
 

int i;  

for (i = 0; i < ABMultiValueGetCount(phoneMulti); i++) {
 

NSString *aPhone = [(NSString*)ABMultiValueCopyValueAtIndex(phoneMulti, i) autorelease];
 

NSString *aLabel = [(NSString*)ABMultiValueCopyLabelAtIndex(phoneMulti, i) autorelease];
 

NSLog(@"PhoneLabel:%@ Phone#:%@",aLabel,aPhone);  

if([aLabel isEqualToString:@"_$!<Mobile>!$_"])
 

{  

[phones addObject:aPhone];  

}  

}  

phoneNo.text=@"";
 

if([phones count]>0)
 

{  

NSString *mobileNo = [phones objectAtIndex:0];
 

phoneNo.text = mobileNo;
 

//NSLog(mobileNo);  

}  

//获取联系人邮箱  

ABMutableMultiValueRef emailMulti = ABRecordCopyValue(person, kABPersonEmailProperty);
 

NSMutableArray *emails = [[NSMutableArray alloc] init];
 

for (i = 0;i < ABMultiValueGetCount(emailMulti); i++)
 

{  

NSString *emailAdress = [(NSString*)ABMultiValueCopyValueAtIndex(emailMulti, i) autorelease];
 

[emails addObject:emailAdress];  

}  

email.text=@"";
 

if([emails count]>0)
 

{  

NSString *emailFirst=[emails objectAtIndex:0];
 

email.text = emailFirst;
 

//NSLog(emailFirst);  

}  

[peoplePicker dismissModalViewControllerAnimated:YES];  

return NO;  

}  

- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker
 

 shouldContinueAfterSelectingPerson:(ABRecordRef)person  

property:(ABPropertyID)property  

  identifier:(ABMultiValueIdentifier)identifier{  

return NO;  



2.AddressBook部分

AddressBook框架部分主要是记录联系人的各个信息,ABRecordRef类型的记录既可以代表单个人(kABPersonType),也可以是一个集合(kABGroupType)。

通讯录中联系人的各个属性有两种形式,单值属性和多值属性。单值属性对应的只有一个值,比如联系人的姓名;多值属性对应的可能有多个值,比如联系人有多个电话号码等。

(a)常用方法


CFTypeRef ABRecordCopyValue (  

   ABRecordRef record,  

   ABPropertyID property  

); 

从一个记录中获取某个属性对应的值

(b)单值属性对应的方法


CFStringRef ABRecordCopyCompositeName (  

   ABRecordRef record  

); 

获取联系人完整的姓名。

(c)多值属性对应的方法


CFTypeRef ABMultiValueCopyValueAtIndex (  

   ABMultiValueRef multiValue,  

   CFIndex index  

); 

返回对应位置处的属性值


CFStringRef ABMultiValueCopyLabelAtIndex (  

   ABMultiValueRef multiValue,  

   CFIndex index  

); 

返回对应位置处的属性标识


CFArrayRef ABMultiValueCopyArrayOfAllValues (  

   ABMultiValueRef multiValue  

); 

返回包含所有属性值的数组


CFIndex ABMultiValueGetCount (  

   ABMultiValueRef multiValue  

); 

返回属性值的个数

例子:


//获取联系人姓名  

name.text = (NSString*)ABRecordCopyCompositeName(person);
 

//获取联系人电话  

ABMutableMultiValueRef phoneMulti = ABRecordCopyValue(person, kABPersonPhoneProperty);
 

NSMutableArray *phones = [[NSMutableArray alloc] init];
 

int i;  

for (i = 0; i < ABMultiValueGetCount(phoneMulti); i++) {
 

NSString *aPhone = [(NSString*)ABMultiValueCopyValueAtIndex(phoneMulti, i) autorelease];
 

NSString *aLabel = [(NSString*)ABMultiValueCopyLabelAtIndex(phoneMulti, i) autorelease];
 

NSLog(@"PhoneLabel:%@ Phone#:%@",aLabel,aPhone);  

if([aLabel isEqualToString:@"_$!<Mobile>!$_"])
 

{  

[phones addObject:aPhone];  

}  



 

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

ag:

//选取联系人的方法

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker 

{

    [self dismissModalViewControllerAnimated:YES];

}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person 

{

return YES;

}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker 

  shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{

NSString* compositeName = (NSString *)ABRecordCopyCompositeName(person);

    contactsAdd.Name = compositeName;

nameTextField.text =compositeName;

    [compositeName release];

ABMultiValueRef phoneProperty = ABRecordCopyValue(person,property);

NSString *phone = (NSString *)ABMultiValueCopyValueAtIndex(phoneProperty,identifier);

contactsAdd.Phone = (NSString*)phone;

phoneTextField.text= (NSString*)phone;

[self dismissModalViewControllerAnimated:YES];

return NO;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: