iphone通讯录AddressBook.framework和AddressBookUI.framework的应用

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

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);

//获取本地通讯录数据库
  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:这个方法进行显示整个通讯录页面

例子:

 
  1. (IBAction)showPicker:(id)sender {  
  2.     ABPeoplePickerNavigationController *picker =  
  3.     [[ABPeoplePickerNavigationController alloc] init];  
  4.     picker.peoplePickerDelegate self;  
  5.     [self presentModalViewController:picker animated:YES];  
  6.    [picker release];  

ABPeoplePickerNavigationControllerDelegate的方法介绍

(1)

 
  1. peoplePickerNavigationControllerDidCancel: 

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

(2)

 
  1. peoplePickerNavigationController:shouldContinueAfterSelectingPerson:  

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

(3)

 
  1. eoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier:  

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

例子:

 
  1. (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {  
  2. // assigning control back to the main controller  
  3. [picker dismissModalViewControllerAnimated:YES];  
  4. }  
  5. (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker 
  6. shouldContinueAfterSelectingPerson:(ABRecordRef)person {  
  7. //获取联系人姓名  
  8. name.text (NSString*)ABRecordCopyCompositeName(person);  
  9. //获取联系人电话  
  10. ABMutableMultiValueRef phoneMulti ABRecordCopyValue(person, kABPersonPhoneProperty);  
  11. NSMutableArray *phones [[NSMutableArray alloc] init];  
  12. int i;  
  13. for (i 0< ABMultiValueGetCount(phoneMulti); i++) {  
  14. NSString *aPhone [(NSString*)ABMultiValueCopyValueAtIndex(phoneMulti, i) autorelease];  
  15. NSString *aLabel [(NSString*)ABMultiValueCopyLabelAtIndex(phoneMulti, i) autorelease];  
  16. NSLog(@"PhoneLabel:%@ Phone#:%@",aLabel,aPhone);  
  17. if([aLabel isEqualToString:@"_$!<Mobile>!$_"])  
  18. {  
  19. [phones addObject:aPhone];  
  20. }  
  21. }  
  22. phoneNo.text=@"";  
  23. if([phones count]>0)  
  24. {  
  25. NSString *mobileNo [phones objectAtIndex:0];  
  26. phoneNo.text mobileNo;  
  27. //NSLog(mobileNo);  
  28. }  
  29. //获取联系人邮箱  
  30. ABMutableMultiValueRef emailMulti ABRecordCopyValue(person, kABPersonEmailProperty);  
  31. NSMutableArray *emails [[NSMutableArray alloc] init];  
  32. for (i 0;i < ABMultiValueGetCount(emailMulti); i++)  
  33. {  
  34. NSString *emailAdress [(NSString*)ABMultiValueCopyValueAtIndex(emailMulti, i) autorelease];  
  35. [emails addObject:emailAdress];  
  36. }  
  37. email.text=@"";  
  38. if([emails count]>0)  
  39. {  
  40. NSString *emailFirst=[emails objectAtIndex:0];  
  41. email.text emailFirst;  
  42. //NSLog(emailFirst);  
  43. }  
  44. [peoplePicker dismissModalViewControllerAnimated:YES];  
  45. return NO;  
  46. }  
  47. (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker  
  48.  shouldContinueAfterSelectingPerson:(ABRecordRef)person  
  49. property:(ABPropertyID)property  
  50.   identifier:(ABMultiValueIdentifier)identifier{  
  51. return NO;  

2.AddressBook部分

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

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

(a)常用方法

 
  1. CFTypeRef ABRecordCopyValue (  
  2.    ABRecordRef record,  
  3.    ABPropertyID property  
  4. ); 

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

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

 
  1. CFStringRef ABRecordCopyCompositeNam(  
  2.    ABRecordRef record  
  3. ); 

获取联系人完整的姓名。

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

 
  1. CFTypeRef ABMultiValueCopyValueAtIndex (  
  2.    ABMultiValueRef multiValue,  
  3.    CFIndex index  
  4. ); 

返回对应位置处的属性值

 
  1. CFStringRef ABMultiValueCopyLabelAtIndex (  
  2.    ABMultiValueRef multiValue,  
  3.    CFIndex index  
  4. ); 

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

 
  1. CFArrayRef ABMultiValueCopyArrayOfAllValues (  
  2.    ABMultiValueRef multiValue  
  3. ); 

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

 
  1. CFIndex ABMultiValueGetCount (  
  2.    ABMultiValueRef multiValue  
  3. ); 

返回属性值的个数

例子:

 
  1. //获取联系人姓名  
  2. name.text (NSString*)ABRecordCopyCompositeName(person);  
  3. //获取联系人电话  
  4. ABMutableMultiValueRef phoneMulti ABRecordCopyValue(person, kABPersonPhoneProperty);  
  5. NSMutableArray *phones [[NSMutableArray alloc] init];  
  6. int i;  
  7. for (i 0< ABMultiValueGetCount(phoneMulti); i++) {  
  8. NSString *aPhone [(NSString*)ABMultiValueCopyValueAtIndex(phoneMulti, i) autorelease];  
  9. NSString *aLabel [(NSString*)ABMultiValueCopyLabelAtIndex(phoneMulti, i) autorelease];  
  10. NSLog(@"PhoneLabel:%@ Phone#:%@",aLabel,aPhone);  
  11. if([aLabel isEqualToString:@"_$!<Mobile>!$_"])  
  12. {  
  13. [phones addObject:aPhone];  
  14. }  

 


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

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;

}



............,....,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

IOS编程:Address Book

在IOS中,允许用户对Address Book(地址簿)进行添加、编辑与删除操作。地址簿可以是一些人的集合,也可以是一系列群组的集合。里面的每一个人都有诸如姓氏、名字、电话号码、电子邮件等一系列属性。这些属性可以只有一个值,当然也可以有多个值,列入,一个人的姓氏只能有一个值,而他/她的电话号码却可以有多个值。

IOS SDK中的AddressBook.Framwork框架允许我们与iOS设备的地址簿数据库进行交互,我们可以通过它取得地址簿上所有人的相关信息,也可以对其中的一条或者多条数据进行查询、删除等操作。

为在应用程序中使用地址簿相关的函数,需要将地址簿框架添加到我们的应用程序中:

  1. 单击Xcode中的工程图标
  2. 选择欲添加地址簿框架的目标
  3. 选择屏幕顶部的Build Phases选项卡
  4. 在Build Phases选项卡中,找到并展开Link Binary选项,单击底部左下角的“+”按钮
  5. 在弹出的库列表中,选中AddressBook.Framwork,点击添加按钮即可

添加地址簿框架后,我们还需要在工程中添加相应的头文件:#import<AddressBook/AddressBook.h>

查询

要进行地址簿的查询操作,首先要使用 ABAddressBookCreate函数创建一个地址簿数据库的引用,该函数返回一个ABAddressBookRef类型的值,如果地址簿数据库不能访问的话,则返回nil。在进行任何地址簿的操作之前,必须检查改制是否为nil,否者,当应用程序试图去编辑一个空的地址簿是,将会以一个运行时错误退出程序。

在取得地址簿引用后,就可以对地址簿进行查询、编辑等操作了,但需要注意的是,一旦你对地址簿进行任何改变,ABAddressBookHasUnsavedChanges函数将返回一个YES值以告知地址簿发生变化了,此时,你可以使用ABAddressBookSave函数或者ABAddressBookRevert函数来保存或者忽略地址簿的变化。

接下来,调用ABAddressBookCopyArrayOfAllPeople函数来得到地址簿中的所有联系人信息,该函数的返回值是一个CFArrayRef类型的数组。之后遍历该数组,调用ABRecoredCopyValue函数便可得到每个联系人的相关信息。它包含两个参数,第一个参数是地址簿记录应用(ABRecordRef),第二个参数指定了你想要获得何种信息。例如,如果想要查询邮件地址,则第二个参数为kABPersonEmailProperty。当然,如果不想自己创建界面去展示这些内容时,我们还可以使用IOS SDK自带的ABPersonViewController(需要引入AddressBookUI.Framwork框架和添加ABPersonViewControllerDeleagte)来展示和编辑联系人的相关信息。示例代码如下:

  ABAddressBookRef abRef = ABAddressBookCreate();

if(abRef != nil){

allarray = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(abRef);

}

CFRelease(abRef);

  ABRecordRef person = [allarray objectAtIndex:[indexPath row]];

cell.textLabel.text = [[[NSString alloc] initWithFormat:@”%@%@”, (__bridge_transfer NSString *)ABRecordCopyValue(person,kABPersonFirstNameProperty), (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty)] autorelease];

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

personView.personViewDelegate = self;

personView.displayedPerson = [allarray objectAtIndex:row];

personView.allowsEditing = YES//是否允许编辑

[self.navigationController pushViewController:personView animated:YES];

[personView release];


编辑

除了调用ABPersonViewController编辑联系人外,还可以使用ABRecordSetValue函数和ABAddressBookAddRecord函数来添加或者修改联系人信息。或者使用IOS SDK自带的ABNewPersonViewController(需要引入AddressBookUI.Framwork框架和添加ABNewPersonViewControllerDeleagte)来添加一个新的联系人,但是别忘记实现相应的代理方法,否则程序会崩溃退出。

  ABAddressBookRef abRef = ABAddressBookCreate();


  CFErrorRef errorRef = NULL;

ABRecordSetValue(abRef,kABPersonFirstNameProperty,(__bridgeCFTypeRef)@”HamGuy”,&errorRef);

ABRecordSetValue(abRef,kABPersonEmailProperty,(__bridgeCFTypeRef)@”wangrui15@gmail.com”,&errorRef);

ABRecordRef person = [allarray objectAtIndex:[indexPath row]];

ABAddressBookAddRecord(abRef, person, &errorRef);

  ABNewPersonViewController *newPersonView = [[ABNewPersonViewControlleralloc] init];

newPersonView.newPersonViewDelegate = self;

  

UINavigationController *newNavigationController = [[UINavigationControlleralloc]

   initWithRootViewController:newPersonView];

[self presentModalViewController:newNavigationController animated:YES];

[newPersonView release];

[newNavigationController release];

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

[newPersonView dismissModalViewControllerAnimated:YES];

}

删除

删除联系人使用ABAddressBookRemoveRecord函数来实现,用法与ABAddressBookAddRecord函数类似,不在赘述。如果要清空地址簿的话,可循环调用该方法实现。

  ABAddressBookRef abRef = ABAddressBookCreate();

if(abRef == nil)

return;

  

CFErrorRef errorRef = NULL;

ABAddressBookRemoveRecord(abRef,[allarray objectAtIndex:[indexPathrow]],&errorRef);


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 可以按照以下步骤编写程序将电子邮件emailaddressbook.txt和电话薄teleaddressbook.txt合并为一个完整的通讯录addressbook.txt: 1. 打开emailaddressbook.txt和teleaddressbook.txt文件,读取文件中的数据。 2. 将两个文件中的数据合并到一个新的列表中。 3. 对列表中的数据进行排序,可以按照姓名、电话号码或电子邮件地址等字段进行排序。 4. 将排序后的数据写入到一个新的文件addressbook.txt中。 5. 关闭所有打开的文件。 下面是一个简单的Python程序示例,可以实现上述功能: ``` # 打开emailaddressbook.txt和teleaddressbook.txt文件 email_file = open('emailaddressbook.txt', 'r') tele_file = open('teleaddressbook.txt', 'r') # 读取文件中的数据 email_data = email_file.readlines() tele_data = tele_file.readlines() # 合并数据到一个新的列表中 address_book = email_data + tele_data # 对列表中的数据进行排序 address_book.sort() # 将排序后的数据写入到一个新的文件addressbook.txt中 address_book_file = open('addressbook.txt', 'w') address_book_file.writelines(address_book) # 关闭所有打开的文件 email_file.close() tele_file.close() address_book_file.close() ``` 注意:上述程序仅供参考,实际应用中可能需要根据具体情况进行修改和优化。 ### 回答2: 合并电子邮件和电话薄成一个完整的通讯录需要编写程序,从而能够更轻松地整合两个文件中的信息。下面将分享如何将两个文件合并为一个完整的通讯录。 首先,需要使用一个编程语言来编写程序,目前比较流行的编程语言有Python,C++,Java等。在这里以Python为例,因为它是一种易学易用的高级编程语言,适合用于快速开发。 接着,需要了解如何读取文件以及将两个文件合并。读取文件使用Python内置的open()函数,需要提供文件名和打开文件模式等参数。在这里,需要打开emailaddressbook.txt和teleaddressbook.txt文件,读取它们各自的信息,并将它们放入一个列表中。 下一步是将两个列表合并为一个,可以使用Python内置的extend()函数将一个列表的元素添加到另一个列表中。这样就可以将电子邮件和电话薄的信息合并到一个列表中。 最后,需要将合并后的信息写入新文件addressbook.txt。此时可以使用Python内置的write()函数来实现。需要遍历新的列表,将列表中的每个元素写入文件中。 以上步骤是将电子邮件和电话薄合并成一个完整通讯录的基本流程。实际过程中可能还需要对数据进行清洗、去重等操作,以保证通讯录中的信息准确无误。 ### 回答3: 编写一个程序将电子邮件地址列表和电话薄合并为完整的通讯录是一项非常实用的任务。这个任务需要一个能够读取文本文件的程序,然后对这些文件进行操作,以便合并它们成一个文件。 首先,我们需要编写一个程序来读取电子邮件地址和电话薄文件。这个程序需要能够打开电子邮件和电话薄文件,读取它们的内容并将它们存储到变量中。然后,它需要将这些变量合并为一个新的通讯录文件。 接下来,我们需要编写一个程序来将这些数据存储到新文件中。这个程序需要打开一个空的通讯录文件,并将电子邮件地址和电话薄数据存储到其中。我们可以使用Python的文件操作命令来完成这个任务。我们需要将电子邮件和电话号码按顺序写入新文件,并在每个条目之间添加适当的分隔符。 在这个过程中,我们还需要解决冲突问题。当我们合并这些文件时,可能会出现重复的联系人信息。为了避免这个问题,我们需要编写代码来检查重复信息,并修改通讯录中的记录,以保留最新的联系人信息。 最后,我们需要检查所有联系人的信息是否已成功地添加到新的通讯录文件中。为了完成这个任务,我们可以编写一个简单的程序来读取新文件,并检查是否缺少任何信息或是否有任何重复的信息。 综上所述,编写一个程序将电子邮件地址和电话薄合并为一个完整的通讯录文件是一个相当复杂的任务,需要处理多个输入源并具有较高的程序处理能力。但如果我们按照上述步骤进行操作,我们可以很容易地编写出这样一个程序。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值