概述

在iOS中,有2个框架可以访问用户的通讯录。从iOS6开始,需要得到用户的授权才能访问通讯录,因此在使用之前,需要检查用户是否已经授权ABAddressBookGetAuthorizationStatus()

授权状态

kABAuthorizationStatusNotDetermined 用户还没有决定是否授权你的程序进行访问
kABAuthorizationStatusRestricted  iOS设备上的家长控制或其它一些许可配置阻止程序与通讯录数据库进行交互
kABAuthorizationStatusDenied  用户明确的拒绝了你的程序对通讯录的访问
kABAuthorizationStatusAuthorized  用户已经授权给你的程序对通讯录进行访问

AddressBook

。纯C语言的API,仅仅是获得联系人数据
。没有提供UI界面展示,需要自己搭建联系人展示界面
。里面的数据类型大部分基于Core Foundation框架

申请访问通讯录

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); //创建通讯录对象
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error){
if (granted) {
NSLog(@"授权成功!");
} else {
NSLog(@"授权失败!");
}
}); //请求访问,granted为YES则请求成功 CFRelease(addressBook); // 释放资源--CF框架需要手动释放

联系人属性

联系人属性包括以下类型:
  简单属性:姓、名等
  多重属性:电话号码、电子邮件等
  组合属性:地址等

(所有的属性常量值都定义在了ABPerson.h头文件中)

一个联系人就是一个ABRecordRef,每个联系人都有自己的属性,比如名字、电话、邮件等

简单属性

使用ABRecordCopyValue(ABRecordRef实例,属性关键字)可以从实例对象中获得对应关键字的属性值

ABPersonCopyLocalizedPropertyName函数可以根据指定的关键字获取对应的标签文本

// 获取所有联系人记录
CFArrayRef array = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSInteger count = CFArrayGetCount(array); for (NSInteger i = ; i < count; ++i) {
// 取出一条记录
ABRecordRef person = CFArrayGetValueAtIndex(array, i); // 取出个人记录中的详细信息
// 名
CFStringRef firstNameLabel = ABPersonCopyLocalizedPropertyName(kABPersonFirstNameProperty);
CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef lastNameLabel = ABPersonCopyLocalizedPropertyName(kABPersonLastNameProperty);
// 姓
CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty); NSLog(@"%@ %@ - %@ %@", lastNameLabel, lastName, firstNameLabel, firstName);
}

多重属性

联系人的有些属性值就没这么简单,一个属性可能会包含多个值
  比如邮箱,分为工作邮箱、住宅邮箱、其他邮箱等
  比如电话,分为工作电话、住宅电话、其他电话等
如果是复杂属性,那么ABRecordCopyValue函数返回的就是ABMultiValueRef类型的数据,例如邮箱或者电话

// 取电话号码
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
// 取记录数量
NSInteger phoneCount = ABMultiValueGetCount(phones);
// 遍历所有的电话号码
for (NSInteger i = ; i < phoneCount; i++) {
  // 电话标签
  CFStringRef phoneLabel = ABMultiValueCopyLabelAtIndex(phones, i);
  // 本地化电话标签
  CFStringRef phoneLocalLabel = ABAddressBookCopyLocalizedLabel(phoneLabel);
  // 电话号码
  CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phones, i);
}

添加联系人

>通过ABPersonCreate函数创建一个新的联系人(返回ABRecordRef)
>通过ABRecordSetValue函数设置联系人的属性
>通过ABAddressBookAddRecord函数将联系人添加到通讯录数据库中
>通过ABAddressBookSave函数保存刚才所作的修改
  可以通过ABAddressBookHasUnsavedChanges函数判断是否有未保存的修改
  当决定是否更改通讯录数据库后,你可以分别使用 AbAddressBookSave 或 ABAddressBookRevert 方式来保存或放弃更改

添加群组

>通过ABPersonCreate函数创建一个新的组(返回ABRecordRef)
>通过ABRecordSetValue函数设置组名
>通过ABAddressBookAddRecord函数将组添加到通讯录数据库中
>通过ABAddressBookSave函数保存刚才所作的修改

操作联系人头像

ABPersonHasImageData
判断通讯录中的联系人是否有图片

ABPersonCopyImageData
取得图片数据(假如有的话)

ABPersonSetImageData
设置联系人的图片数据

AddressBookUI.framework

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

通过ABPeoplePickerNavigationController操作,简单方便,无需自己搭建界面;

ABPeoplePickerNavigationController的代理属性为:peoplePickerDelegate(注:非常见的delegate)
AddressBookUI的协议在iOS8时有修改,协议方法有修改:

// 在iOS7时 点击cancle按钮时候就会调用
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
NSLog(@"%s", __func__);
// 关闭通讯录
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
} // 在iOS7时 , 选中某一个联系人就会调用
// 返回一个BOOL值, 如果返回NO, 代表不会进入下一层(详情), 如果返回YES,代表会进入下一层
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
NSLog(@"%s", __func__); /*
//取出当前联系人的的电话信息
// 获取练习人得姓名
CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSLog(@"%@ %@", firstName, lastName);
// 获取联系人的电话
// 从联系人中获取到得电话是所有的电话
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
// 获取当前联系人总共有多少种电话
CFIndex phoneCount = ABMultiValueGetCount(phones); for (int i = 0; i < phoneCount; i++) {
CFStringRef name = ABMultiValueCopyLabelAtIndex(phones, i);
// 从所有的电话中取出指定的电话
CFStringRef value = ABMultiValueCopyValueAtIndex(phones, i);
NSLog(@"name = %@ value = %@", name, value);
}
*/
return YES;
} // 在iOS7时 , 选中某一个联系人的某一个属性时就会调用
// 返回一个BOOL值, 如果返回NO, 代表不会进行下一步操作(打电话, 打开日历....), 如果返回YES,代表会进行下一步操作
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
NSLog(@"%s", __func__); return YES;
} #pragma mark - iOS8
// 选中某一个联系人就会调用
#warning 只要实现了这个方法, 就不会进行下一步操作(进入详情), iOS8的做法是默认返回NO
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
NSLog(@"%s", __func__);
} // 选中某一个联系人的某一个属性时就会调用
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
NSLog(@"%s", __func__);
}

第三方框架:RHAddressBook

不论是AddressBook还是AddressBookUI,在操作联系人属性时都只能用CF代码,不方便;

RHAddressBook可以以纯OC方式操作,提供了很大的便利

- (void)viewDidLoad {
[super viewDidLoad]; // 1.创建通讯录
self.ab = [[RHAddressBook alloc] init]; // 2.判断是否授权
if ([RHAddressBook authorizationStatus] == RHAuthorizationStatusNotDetermined){ // 3.主动请求授权
[self.ab requestAuthorizationWithCompletion:^(bool granted, NSError *error) {
if (granted) {
NSLog(@"授权成功");
}else
{
NSLog(@"授权失败");
}
}];
}
} - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSArray *allPeople = [self.ab people];
for (RHPerson *person in allPeople) {
NSLog(@"%@", person);
}
}

AddressBook/AddressBookUI的更多相关文章

  1. iOS各个版本的新特性介绍

    官方汇总 What's News in iOS iOS 9.3 to iOS 10.0 API Differences Objective-C /usr/include Accelerate Audi ...

  2. iOS中的zxing集成步骤

    参照网上各大神文章,自己总结了下如下,欢迎大家指正与交流!(主参照:http://blog.csdn.net/brokge/article/details/9045629) 1. 到 github下载 ...

  3. zxing 二维码扫描 配置和使用

    本文转载至 http://blog.csdn.net/a6472953/article/details/8796501   二维码扫描使用最多的主要有两个库:zbarSDK 和zxing 关于zbar ...

  4. Swift - 访问通讯录-使用AddressBook.framework和AddressBookUI.framework框架实现

    1,通讯录访问介绍 通讯录(或叫地址簿,电话簿)是一个数据库,里面储存了联系人的相关信息.要实现访问通讯录有如下两种方式: (1)AddressBook.framework框架 : 没有界面,通过代码 ...

  5. 【转】iPhone通讯录AddressBook.framework和AddressBookUI.framework的应用

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

  6. (一〇〇)使用AddressBookUI实现通讯录操作

    上节提到使用AddressBook可以实现通讯录数据的获取,但有时需要用户自己选取联系人或者联系人信息,这时候就要借助AddressBookUI框架的ABPeoplePickerNavigationC ...

  7. iOS-----使用AddressBookUI管理联系人

    使用AddressBookUI管理联系人 iOS SDK为管理地址簿提供的视图控制器位于AddressBookUI框架内.总结来说,AddressBookUI框架提供了如下特殊的视图控制器. ABPe ...

  8. iOS-----使用AddressBook管理联系人

    使用AddressBook管理联系人 iPhone手机通常都是自带的Contacts应用,包括所有联系人的性(last name).名(first name).电话.E-mail地址.住址.生日等各种 ...

  9. 利用AddressBook.framework框架获取iOS系统通讯录数据

    此方法是使用AddressBook.framework框架获取通讯录信息 第一步.在info.plist文件里面配置访问权限 第二步.导入头文件 #import <AddressBook/Add ...

随机推荐

  1. CSS中的间距设置与盒子模型

    CSS间距 内补白 外补白 盒子模型 CSS间距 很多时候我们为了美观,需要对内容进行留白设置,这时候就需要设置间距了. 内补白 设置元素的内间距 padding: 检索或设置对象四边的内部边距 pa ...

  2. 【大数据 Spark】利用电影观看记录数据,进行电影推荐

    利用电影观看记录数据,进行电影推荐. 目录 利用电影观看记录数据,进行电影推荐. 准备 1.任务描述: 2.数据下载 3.部分数据展示 实操 1.设置输入输出路径 2.配置spark 3.读取Rati ...

  3. 中文分词工具简介与安装教程(jieba、nlpir、hanlp、pkuseg、foolnltk、snownlp、thulac)

    2.1 jieba 2.1.1 jieba简介 Jieba中文含义结巴,jieba库是目前做的最好的python分词组件.首先它的安装十分便捷,只需要使用pip安装:其次,它不需要另外下载其它的数据包 ...

  4. Owin Katana 的底层源码分析

    最近看了一下开源项目asp.net katana,感觉公开的接口非常的简洁优雅,channel 9 说是受到node.js的启发设计的,Katana是一个比较老的项目,现在已经整合到asp.net c ...

  5. 【STM32系列汇总】小白博主的STM32实战快速进阶之路(持续更新)

    我把之前在学习和工作中使用STM32进行嵌入式开发的经验和教程等相关整理到这里,方便查阅学习,如果能帮助到您,请帮忙点个赞: 本文的宗旨 STM32 只是一个硬件平台,同样地他可以换成MSP430,N ...

  6. STM32 使用IQmath实现SVPWM

    IQMATH TI的片子很香,做的也很好,但是成本相对ST会更高,电机控制方面,TI无疑是做的最好的方案之一,另外TI针对没有浮点运算器的定点DSP推出了IQMATH库,在使用Q格式对数据进行分析和处 ...

  7. webpack的proxytable的配置

    这个一定不能忘记了/rest/后面的/,否则就是404找不到接口 这样的实现效果是 this.axios.post('/api/delShare', qs.stringify({'Id':Number ...

  8. 深入理解Java虚拟机第三版,总结笔记【随时更新】

    最近一直在看<深入理解Java虚拟机>第三版,无意中发现了第三版是最近才发行的,听说讲解的JDK版本升级,新增了近50%的内容. 这种神书,看懂了,看进去了,真的看的很快,并没有想象中的晦 ...

  9. BZOJ1022

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2701  Solved: 1721[Submit] ...

  10. LibreOJ #515 贪心只能过样例

    题目链接:https://loj.ac/problem/515 知识点: DP.bitset类 解题思路: DP部分不难想到:从 a 到 b 遍历,然后在已有的状态上加上遍历得到的数字的平方,难点在于 ...