iOS 获得通讯录中联系人的所有属性--b

ABAddressBookRef addressBook = ABAddressBookCreate();

    CFArrayRef results = ABAddressBookCopyArrayOfAllPeople(addressBook);
    
    for(int i = 0; i < CFArrayGetCount(results); i++)
    {
        ABRecordRef person = CFArrayGetValueAtIndex(results, i);
        //读取firstname
        NSString *personName = (NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        if(personName != nil)
            textView.text = [textView.text stringByAppendingFormat:@"n姓名:%@n",personName];
        //读取lastname
        NSString *lastname = (NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
        if(lastname != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",lastname];
        //读取middlename
        NSString *middlename = (NSString*)ABRecordCopyValue(person, kABPersonMiddleNameProperty);
        if(middlename != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",middlename];
        //读取prefix前缀
        NSString *prefix = (NSString*)ABRecordCopyValue(person, kABPersonPrefixProperty);
        if(prefix != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",prefix];
        //读取suffix后缀
        NSString *suffix = (NSString*)ABRecordCopyValue(person, kABPersonSuffixProperty);
        if(suffix != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",suffix];
        //读取nickname呢称
        NSString *nickname = (NSString*)ABRecordCopyValue(person, kABPersonNicknameProperty);
        if(nickname != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",nickname];
        //读取firstname拼音音标
        NSString *firstnamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonFirstNamePhoneticProperty);
        if(firstnamePhonetic != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",firstnamePhonetic];
        //读取lastname拼音音标
        NSString *lastnamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonLastNamePhoneticProperty);
        if(lastnamePhonetic != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",lastnamePhonetic];
        //读取middlename拼音音标
        NSString *middlenamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonMiddleNamePhoneticProperty);
        if(middlenamePhonetic != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",middlenamePhonetic];
        //读取organization公司
        NSString *organization = (NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);
        if(organization != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",organization];
        //读取jobtitle工作
        NSString *jobtitle = (NSString*)ABRecordCopyValue(person, kABPersonJobTitleProperty);
        if(jobtitle != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",jobtitle];
        //读取department部门
        NSString *department = (NSString*)ABRecordCopyValue(person, kABPersonDepartmentProperty);
        if(department != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",department];
        //读取birthday生日
        NSDate *birthday = (NSDate*)ABRecordCopyValue(person, kABPersonBirthdayProperty);
        if(birthday != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",birthday];
        //读取note备忘录
        NSString *note = (NSString*)ABRecordCopyValue(person, kABPersonNoteProperty);
        if(note != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@n",note];
        //第一次添加该条记录的时间
        NSString *firstknow = (NSString*)ABRecordCopyValue(person, kABPersonCreationDateProperty);
        NSLog(@"第一次添加该条记录的时间%@n",firstknow);
        //最后一次修改該条记录的时间
        NSString *lastknow = (NSString*)ABRecordCopyValue(person, kABPersonModificationDateProperty);
        NSLog(@"最后一次修改該条记录的时间%@n",lastknow);
        
        //获取email多值
        ABMultiValueRef email = ABRecordCopyValue(person, kABPersonEmailProperty);
        int emailcount = ABMultiValueGetCount(email);    
        for (int x = 0; x < emailcount; x++)
        {
            //获取email Label
            NSString* emailLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(email, x));
            //获取email值
            NSString* emailContent = (NSString*)ABMultiValueCopyValueAtIndex(email, x);
            textView.text = [textView.text stringByAppendingFormat:@"%@:%@n",emailLabel,emailContent];
        }
        //读取地址多值
        ABMultiValueRef address = ABRecordCopyValue(person, kABPersonAddressProperty);
        int count = ABMultiValueGetCount(address);    
        
        for(int j = 0; j < count; j++)
        {
            //获取地址Label
            NSString* addressLabel = (NSString*)ABMultiValueCopyLabelAtIndex(address, j);
            textView.text = [textView.text stringByAppendingFormat:@"%@n",addressLabel];
            //获取該label下的地址6属性
            NSDictionary* personaddress =(NSDictionary*) ABMultiValueCopyValueAtIndex(address, j);        
            NSString* country = [personaddress valueForKey:(NSString *)kABPersonAddressCountryKey];
            if(country != nil)
                textView.text = [textView.text stringByAppendingFormat:@"国家:%@n",country];
            NSString* city = [personaddress valueForKey:(NSString *)kABPersonAddressCityKey];
            if(city != nil)
                textView.text = [textView.text stringByAppendingFormat:@"城市:%@n",city];
            NSString* state = [personaddress valueForKey:(NSString *)kABPersonAddressStateKey];
            if(state != nil)
                textView.text = [textView.text stringByAppendingFormat:@"省:%@n",state];
            NSString* street = [personaddress valueForKey:(NSString *)kABPersonAddressStreetKey];
            if(street != nil)
                textView.text = [textView.text stringByAppendingFormat:@"街道:%@n",street];
            NSString* zip = [personaddress valueForKey:(NSString *)kABPersonAddressZIPKey];
            if(zip != nil)
                textView.text = [textView.text stringByAppendingFormat:@"邮编:%@n",zip];    
            NSString* coutntrycode = [personaddress valueForKey:(NSString *)kABPersonAddressCountryCodeKey];
            if(coutntrycode != nil)
                textView.text = [textView.text stringByAppendingFormat:@"国家编号:%@n",coutntrycode];    
        }
        
        //获取dates多值
        ABMultiValueRef dates = ABRecordCopyValue(person, kABPersonDateProperty);
        int datescount = ABMultiValueGetCount(dates);    
        for (int y = 0; y < datescount; y++)
        {
            //获取dates Label
            NSString* datesLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(dates, y));
            //获取dates值
            NSString* datesContent = (NSString*)ABMultiValueCopyValueAtIndex(dates, y);
            textView.text = [textView.text stringByAppendingFormat:@"%@:%@n",datesLabel,datesContent];
        }
        //获取kind值
        CFNumberRef recordType = ABRecordCopyValue(person, kABPersonKindProperty);
        if (recordType == kABPersonKindOrganization) {
            // it's a company
            NSLog(@"it's a companyn");
        } else {
            // it's a person, resource, or room
            NSLog(@"it's a person, resource, or roomn");
        }
        
        
        //获取IM多值
        ABMultiValueRef instantMessage = ABRecordCopyValue(person, kABPersonInstantMessageProperty);
        for (int l = 1; l < ABMultiValueGetCount(instantMessage); l++)
        {
            //获取IM Label
            NSString* instantMessageLabel = (NSString*)ABMultiValueCopyLabelAtIndex(instantMessage, l);
            textView.text = [textView.text stringByAppendingFormat:@"%@n",instantMessageLabel];
            //获取該label下的2属性
            NSDictionary* instantMessageContent =(NSDictionary*) ABMultiValueCopyValueAtIndex(instantMessage, l);        
            NSString* username = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageUsernameKey];
            if(username != nil)
                textView.text = [textView.text stringByAppendingFormat:@"username:%@n",username];
            
            NSString* service = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageServiceKey];
            if(service != nil)
                textView.text = [textView.text stringByAppendingFormat:@"service:%@n",service];            
        }
        
        //读取电话多值
        ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);
        for (int k = 0; k<ABMultiValueGetCount(phone); k++)
        {
            //获取电话Label
            NSString * personPhoneLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phone, k));
            //获取該Label下的电话值
            NSString * personPhone = (NSString*)ABMultiValueCopyValueAtIndex(phone, k);
                
            textView.text = [textView.text stringByAppendingFormat:@"%@:%@n",personPhoneLabel,personPhone];
        }
        
        //获取URL多值
        ABMultiValueRef url = ABRecordCopyValue(person, kABPersonURLProperty);
        for (int m = 0; m < ABMultiValueGetCount(url); m++)
        {
            //获取电话Label
            NSString * urlLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(url, m));
            //获取該Label下的电话值
            NSString * urlContent = (NSString*)ABMultiValueCopyValueAtIndex(url,m);
            
            textView.text = [textView.text stringByAppendingFormat:@"%@:%@n",urlLabel,urlContent];
        }
        
        //读取照片
        NSData *image = (NSData*)ABPersonCopyImageData(person);
            

        UIImageView *myImage = [[UIImageView alloc] initWithFrame:CGRectMake(200, 0, 50, 50)];
        [myImage setImage:[UIImage imageWithData:image]];
        myImage.opaque = YES;
        [textView addSubview:myImage];
        

    
    }
    
    CFRelease(results);
    CFRelease(addressBook);

 

===============================================

附上

iOS 通讯录信息读取兼容的实现方法

项目中有一个功能需要读取通讯录中联系人的手机。在iOS8以前都是可用的,主要使用如下三个代理方法来实现

1
- (void) peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
1
2
- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)
peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person  
1
2
3
4
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
  return NO;
}

但是iOS8更新以后,悲剧的事情发生了:

1
2
3
4
5
// Deprecated, use predicateForSelectionOfPerson and/or -peoplePickerNavigationController:didSelectPerson: instead.
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person NS_DEPRECATED_IOS(2_0, 8_0);
  
// Deprecated, 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);

其中两个方法被干掉了(对于iOS开发者来说来说这种情况太常见了)

参考文档发现可以使用如下两个方法来代替:

1
2
3
4
5
// Called after a person has been selected by the user.
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person NS_AVAILABLE_IOS(8_0);
  
// Called after a property has been selected by the user.
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier NS_AVAILABLE_IOS(8_0);

这两个方法是这样的,因为iOS8以后通讯录的结构有所变化:第一层是人名列表,点击某个人名进去之后是这个人的详细信息。

其中:

第一个方法是选中这个人之后调用。

第二个方法是选中这个人的详细信息后调用。

解析具体信息的代码可以完全不变

======================2017.7.13更新==========

一、iOS 9 以前的通讯录框架

AddressBookUI框架:提供了联系人列表界面、联系人详情界面、添加联系人界面等,一般用于选择联系人。

AddressBook 框架:纯 C 语言的 API,仅仅是获得联系人数据。没有提供 UI 界面展示,需要自己搭建联系人展示界面。

二、 iOS 9 以后最新通讯录框架

ContactsUI 框架:拥有 AddressBookUI 框架的所有功能,使用起来更加的面向对象。

Contacts 框架:拥有 AddressBook框架的所有功能,不再是 C 语言的 API,使用起来非常简单。

这次主要说下iOS9以后获取手机通讯录的方法:

所需框架

1
#import <ContactsUI/ContactsUI.h>

遵循代理

1
<CNContactPickerDelegate>

1、请求授权判断

1
2
3
4
5
6
// 判断当前的授权状态
if (status != CNAuthorizationStatusAuthorized) {
 
 UIAlertView * alart = [[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"请您设置允许APP访问您的通讯录\n设置-隐私-通讯录" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
 return;
}

这个说下几个授权状态,和AddressBook的差不多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef NS_ENUM(NSInteger, CNAuthorizationStatus)
{
/*! 用户尚未就应用程序是否可以访问联系人数据做出选择。 */
CNAuthorizationStatusNotDetermined = 0,
 
/*! 该应用程序没有权限访问联系人数据。
 *用户无法更改此应用程序的状态,可能是由于主动限制(如父母控制到位)。 */
CNAuthorizationStatusRestricted,
 
/*! 用户明确拒绝对应用程序的联系人数据的访问。 */
CNAuthorizationStatusDenied,
 
/*! 该应用程序被授权访问联系人数据。 */
CNAuthorizationStatusAuthorized
}

判断

1
2
3
4
5
6
7
8
9
10
11
12
// 判断当前的授权状态是否是用户还未选择的状态
if (status == CNAuthorizationStatusNotDetermined)
{
CNContactStore *store = [CNContactStore new];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
  if (granted){
    NSLog(@"授权成功!");
  }else{
    NSLog(@"授权失败!");
  }
}];
}

2、创建通讯录控制器

1
2
3
4
5
6
7
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//iOS 10
//  AB_DEPRECATED("Use CNContactPickerViewController from ContactsUI.framework instead")
CNContactPickerViewController * contactVc = [CNContactPickerViewController new];
contactVc.delegate = self;
[self presentViewController:contactVc animated:YES completion:nil];
}

如果在iOS10的机器上调用以前的ABPeoplePickerNavigationController老方法将直接崩溃。所以如果还是用以前的方法,则需要加判断版本判断

3、实现代理方法,获取单人信息(1.点击姓名显示详情 2.不显示详情)

1
2
3
4
5
6
7
8
9
// 选择某个联系人时调用
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty
{
CNContact *contact = contactProperty.contact;
NSString *name = [CNContactFormatter stringFromContact:contact style:CNContactFormatterStyleFullName];
CNPhoneNumber *phoneValue= contactProperty.value;
NSString *phoneNumber = phoneValue.stringValue;
NSLog(@"%@--%@",name, phoneNumber);
}

代理方法说明

1
2
3
4
5
6
7
8
9
10
// 1.选择联系人时使用(不展开详情)
- (void)contactPicker:(CNContactPickerViewController   *)picker didSelectContact:(CNContact *)contact;
 
注:如果有上面的方法,下面的方法不执行
 
// 2.选择联系人某个属性时调用(展开详情)
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;
 
// 3.取消选中联系人时调用
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker;

4、取消选择的回调

1
2
3
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker{
[picker dismissViewControllerAnimated:YES completion:nil];
}

到此上面的过程便可得到通讯录中一个人的信息,下面说一下获取手机的整体通讯录方法(获取全部联系人信息)

5、获取全部通讯录信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 创建通讯录对象
CNContactStore *contactStore = [CNContactStore new];
NSArray *keys = @[CNContactPhoneNumbersKey,CNContactGivenNameKey];
// 获取通讯录中所有的联系人
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
 
[contactStore enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
 
// 获取姓名
//  NSString *firstName = contact.familyName;
NSString *lastName = contact.givenName;
 
NSLog(@"name: %@",lastName);
 
// 获取电话号码
 
for (CNLabeledValue *labeledValue in contact.phoneNumbers){
 
  CNPhoneNumber *phoneValue = labeledValue.value;
  NSString *phoneNumber = phoneValue.stringValue;
  NSLog(@"number: %@",phoneNumber);
}
  }];

posted on 2015-10-13 21:21  &#127774;Bob  阅读(307)  评论(0编辑  收藏  举报

导航