概述

在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. 使用Hystrix的插件机制,解决在使用线程隔离时,threadlocal的传递问题

    背景 在我们的项目中,比较广泛地使用了ThreadLocal,比如,在filter层,根据token,取到用户信息后,就会放到一个ThreadLocal变量中:在后续的业务处理中,就会直接从当前线程, ...

  2. RabbitMQ|异步

    目录 RabbitMQ|异步 1 概念|异步 1.1 同步与异步 1.2 比喻 2 生产者消费者设计模式 3 RabbitMQ介绍 3.1 主流消息队列比较: 3.2 RabbitMQ安装(mac电脑 ...

  3. 【Hadoop离线基础总结】工作流调度器azkaban

    目录 Azkaban概述 工作流调度系统的作用 工作流调度系统的实现 常见工作流调度工具对比 Azkaban简单介绍 安装部署 Azkaban的编译 azkaban单服务模式安装与使用 azkaban ...

  4. Mysql常用sql语句(九)- like 模糊查询

    测试必备的Mysql常用sql语句,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1683347.html 前言 ...

  5. Android广播时间——实现强制下线功能

    目录 思路:强制下线功能需要先关闭掉所有的活动,然后回到登录界面. 步骤 1.关闭所有活动 2.创建BaseActivity类作为所有活动的父类,因为需要用ActivityCollector管理所有活 ...

  6. CentOS7 Installing Python3

    最近开始学习python. python火了这么久,我终于还是跪舔它了,我是一个跟风的人,学过C.C#.JAVA.PHP,无一例外的浅尝即止,不知道我这双已经近视的眼,确认过的眼神还对不对,希望pyt ...

  7. JS插件:fullCalendar图解

    1.首先看下效果: 官网下载链接 https://fullcalendar.io/download .官方效果图:https://fullcalendar.io/ 2.准备工作,引入对应的 css和 ...

  8. Web_php_unserialize

    0x01 <?php class Demo { private $file = 'index.php'; public function __construct($file) { $this-& ...

  9. Python-AES加密算法接口测试

    前言 先前已经学过了Python-SHA256加密算法接口测试,今天我跟大家讲解一下AES加密算法的接口如何写python脚本进行测试. 一:安装pycryptodome模块 pip install ...

  10. RobotFramework Selenium2Library 关键字详解

    *** Settings *** Library Selenium2Library *** Keywords *** Checkbox应该不被选择 [Arguments] ${locator} Che ...