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

iOS 获得通讯录中联系人的所有属性--b的更多相关文章

  1. ios 获得通讯录中联系人的所有属性 亲测,可行 兼容io6 和 ios 7

    //获取通讯录中的所有属性,并存储在 textView 中,已检验,切实可行.兼容io6 和 ios 7 ,而且ios7还没有权限确认提示. -(void)getAddressBook { ABAdd ...

  2. IOS 获得通讯录中联系人的所有属性 备用参考

    ABAddressBookRef addressBook = ABAddressBookCreate(); CFArrayRef results = ABAddressBookCopyArrayOfA ...

  3. iOS 获取通讯录中联系人的所有属性 by - zfqj

    1 ABAddressBookRef addressBook = ABAddressBookCreate(); 2 3 CFArrayRef results = ABAddressBookCopyAr ...

  4. IOS 获取通讯录中信息

    获取通讯录中信息 一. 我们设置一个ABAddressBookRef类型的属性addressBook. 二. 要获得通讯录中的信息,我们需要获取访问通讯录的权限. 在运行下面的获取权限的方法的时候,系 ...

  5. iOS获取通讯录所有联系人信息

    以下是2种方式: 第一种方法: GetAddressBook.h #import <Foundation/Foundation.h> @interface GetAddressBook : ...

  6. 【实用篇】获取Android通讯录中联系人信息

    第一步,在Main.xml布局文件中声明一个Button控件,布局文件代码如下: <LinearLayout xmlns:android="http://schemas.android ...

  7. iOS有关通讯录操作

    一.首先获取用户通讯录授权信息. 在AppDelegate中导入#import <AddressBook/AddressBook.h>框架,在下列方法中获取授权信息. - (BOOL)ap ...

  8. ios读取通讯录信息

    ios读取通讯录信息 (2012-05-22 14:07:11) 标签: ios读取通讯录 it   iphone如许app读取通讯录信息,读取通讯录信息时需要加载AddressBookUI 和Add ...

  9. IOS 获取系统通讯录中的联系人信息

    - (IBAction)getAllContactFromSystem { ABAddressBookRef ab = ABAddressBookCreateWithOptions(NULL, NUL ...

随机推荐

  1. Java容器-引用分类与部分Map用法

    目录 1.引用分类 2.了解WeakHashMap.IdentityHashMap.EnumMap 3.同步控制与只读设置 代码实现 1.引用分类(面试) 强引用(StrongReference):引 ...

  2. CentOS 6.9/7通过yum安装指定版本的PostgreSQL

    PostgreSQL(10+) 一.安装PostgreSQL // 安装EPEL源 # wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel- ...

  3. 从网络得到数据--Arduino+以太网

    昨天我们讨论了如何使用Arduino以太网插板建立服务器,并通过网络控制Arduino的引脚.今天我们来看看用插板做为客户端来从一个网页上得到信息并返回报告.我几个月前用的这个方法,当时我做了一个Ni ...

  4. Add current boost to a USB charger

    The popular USB interface can charge a portable device while transferring data. But for high-capacit ...

  5. Git 中文件的状态和流转区

    Git的文件主要处于三种状态,分别是 staged, modified, committed. Git文件流转有三个区域,分别是 工作区域. 索引区域. 本地数据区域. 要修改对一个文件进行操作,首先 ...

  6. ELM327 OBD to RS232 Interpreters

    http://elmelectronics.com/DSheets/ELM327DS.pdf

  7. Shuttle ESB(四)——公布订阅模式实例介绍(1)

    前面,我已经集中用了三篇文章来讲Shuttle ESB的入门实例与宏观概念. Shuttle ESB一共同拥有两种发送消息的模式:请求/对应模式与Pub/Sub模式. 关于这两种模式的区分.请看以下文 ...

  8. 配置Android-Annotation (github20大开源:http://www.eoeandroid.com/thread-278980-1-1.html)

    1. 把androidannotations-X.X.X-api.jar 放在libs文件夹 2. 把androidannotations-X.X.X.jar 放在文件夹compile-libs,1与 ...

  9. FFMPEG类库打开流媒体的方法(传参数)

    使用ffmpeg类库进行开发的时候,打开流媒体(或本地文件)的函数是avformat_open_input(). 其中打开网络流的话,前面要加上函数avformat_network_init(). 一 ...

  10. js隐藏表格的一行数据

    1.方法 document.getElementById('customerAccount_tr').style.display="";//缴纳人名称显示 document.get ...