一、iOS8.0

1、访问用户通讯录的两个框架

(1)AddressBookUI.framework

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

(2)AddressBook.framework

  <1>纯C语言的API,仅仅是获得联系人数据

  <2>没有提供UI界面展示,需要自己搭建联系人展示界面

  <3>里面的数据类型大部分基于Core Foundation框架,使用起来非常不方便

(3)从iOS6开始,需要得到用户的授权才能访问通讯录(没UI界面的),因此在使用之前,需要检查用户是否已经授权

获得通讯录的授权状态:ABAddressBookGetAuthorizationStatus()

2、使用AddressBookUI.framework示例

#import "ViewController.h"
#import <AddressBookUI/AddressBookUI.h>
@interface ViewController () <ABPeoplePickerNavigationControllerDelegate> @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//创建通讯录控制器
//弹出控制器
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc]init]; //设置代理
picker.peoplePickerDelegate = self; //展示通讯录界面
[self presentViewController:picker animated:YES completion:nil]; } //选中一个人的基本信息就会调用
//参数1:控制器 参数2:选择的person的信息
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
/*
1、关于内存的管理:静态分析工具 2、因为是C语言的API(CoreFoundation),所有使用了create、copy等获取的对象都需要释放 -> CFRelease 3、桥接
__bridge 默认桥接
__bridge_transfer 桥接 coreF -> ocF 转让对象的所有权(释放权)
__bridge_retained 桥接 ocF -> coreF 转让对象的所有权
*/ //返回的ABRecordRef是一条记录,包括了一个人的所有信息字段
//通过“函数”获得姓名
CFStringRef strfirst = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef strlast = ABRecordCopyValue(person, kABPersonLastNameProperty); //在桥接时,转让了对象的所有权,转给了OC来管理(自动释放了)
NSString *strF = (__bridge_transfer NSString *)(strfirst);
NSString *strL = (__bridge_transfer NSString *)(strlast);
NSLog(@"%@ %@",strF,strL); //电话号码:ABMultiValueRef 封装一个保存了很多电话的一个类型,类似OC中的数组
ABMultiValueRef multiValues = ABRecordCopyValue(person, kABPersonPhoneProperty);
//获得这个集合的数量(电话号码的数量)
CFIndex index = ABMultiValueGetCount(multiValues);
//遍历集合,打印电话
for (CFIndex i = 0; i < index; i++) { CFStringRef strPhone = ABMultiValueCopyValueAtIndex(multiValues, i);
NSString *phoneStr = (__bridge_transfer NSString *)(strPhone);
NSLog(@"%@",phoneStr);
} //释放内存前,先判断该字段存在
if (multiValues != NULL) {
CFRelease(multiValues);
} } //选择中一个人信息的属性才会调用
//注意点:如果实现“选中个人信息的代理方法” 当前方法不执行,因为属性界面不会显示
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
NSLog(@"property %zd",property);
} //点击取消了 就会调用
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
NSLog(@"peoplePickerNavigationControllerDidCancel");
}

3、使用AddressBook.framework框架示例

#import "ViewController.h"
#import <AddressBook/AddressBook.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //获取用户的授权:授权状态
/*
kABAuthorizationStatusNotDetermined = 0, // deprecated, use CNAuthorizationStatusNotDetermined
kABAuthorizationStatusRestricted, // deprecated, use CNAuthorizationStatusRestricted
kABAuthorizationStatusDenied, // deprecated, use CNAuthorizationStatusDenied
kABAuthorizationStatusAuthorized // 已经授权
*/ //通过函数获得授权状态
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); if (status == kABAuthorizationStatusNotDetermined) { ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
//申请授权
//参数1 通讯录对象 参数2block 回调
ABAddressBookRequestAccessWithCompletion(book, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(@"授权成功!");
}else{
NSLog(@"授权失败!");
}
});
}
} - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取联系人信息
//获得姓名 //通讯录是单例,在哪里获取都是一样的
ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL); //获取所有人的信息
CFArrayRef allpeople = ABAddressBookCopyArrayOfAllPeople(book); //数量
CFIndex count = CFArrayGetCount(allpeople); for (CFIndex i = 0; i <count ; i++) { //获得没一条记录
ABRecordRef record = CFArrayGetValueAtIndex(allpeople, i); //获得姓名
CFStringRef strFirst = ABRecordCopyValue(record, kABPersonFirstNameProperty);
NSString *str = (__bridge_transfer NSString *)strFirst;
NSLog(@"%@",str); //获得电话号码
ABMultiValueRef multivalue = ABRecordCopyValue(record, kABPersonPhoneProperty); for (CFIndex i = 0; i < ABMultiValueGetCount(multivalue); i++) {
CFStringRef phoneStr = ABMultiValueCopyValueAtIndex(multivalue, i);
NSString *phone = (__bridge_transfer NSString *)(phoneStr); NSLog(@"%@",phone);
} CFRelease(multivalue); } CFRelease(allpeople);
CFRelease(book); }
@end

二、iOS9.0

1、访问用户通讯录的两个框架

(1)ContactsUI

  <1>AddressBookUI的升级,不需要授权

  <2>通过代理返回需要的数据

(2)Contacts

  AddressBook.framework 的升级

2、ContactsUI示例

#import "ViewController.h"
#import <ContactsUI/ContactsUI.h>
@interface ViewController ()<CNContactPickerDelegate> @end @implementation ViewController - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//不需要授权
//创建通讯录控制器
CNContactPickerViewController *picker = [[CNContactPickerViewController alloc]init];
//设置代理拿到数据本身
picker.delegate = self;
//展示通讯录
[self presentViewController:picker animated:YES completion:nil];
} //实现代理方法
//选择一个联系人的基本信息
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact;
{ //重点注意contact的类型和属性 NSArray *allArray = contact.phoneNumbers;
for (CNLabeledValue * labeledValue in allArray) {
CNPhoneNumber *num = labeledValue.value;
NSLog(@"num = %@",num.stringValue);
NSLog(@"===%@ ===%@",labeledValue.value,labeledValue.label);
}
}
//选择一个联系人属性信息
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;
{
NSLog(@"didSelectContactProperty");
} @end

3、Contacts示例

#import "ViewController.h"
#import <Contacts/Contacts.h>
@interface ViewController ()
@property (nonatomic, strong) CNContactStore *store;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //获取授权状态
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]; //如果没有授权过需要请求用户的授权
CNContactStore *store = [[CNContactStore alloc]init];
self.store = store; if (status == CNAuthorizationStatusNotDetermined) {
//请求授权
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { if (granted) {
NSLog(@"授权成功!");
}else{
NSLog(@"授权失败!");
} }];
} }
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//name phone
CNContactFetchRequest *request = [[CNContactFetchRequest alloc]initWithKeysToFetch:@[CNContactGivenNameKey,CNContactPhoneNumbersKey]]; //参数1 封装查询请求
[self.store enumerateContactsWithFetchRequest: request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
//返回的数据 CNContact
NSLog(@"%@",contact.givenName); NSLog(@"%@",contact.phoneNumbers); }];
}
@end

iOS通讯录(纯纯的干货)的更多相关文章

  1. iOS 通讯录空格

    iOS 通讯录联系人出现 ASCII 码值为 160 的空格  NOTE:       这里的"空格"是指 在通讯录中取出的联系人中带有特殊空格 带有特殊空格的字符串 " ...

  2. Xamarin.Forms读取并展示Android和iOS通讯录 - TerminalMACS客户端

    Xamarin.Forms读取并展示Android和iOS通讯录 - TerminalMACS客户端 本文同步更新地址: https://dotnet9.com/11520.html https:// ...

  3. iOS 通讯录-获取联系人属性

    内容均来自关东升老师的ios开发指南 上一篇写了联系人框架的一些必须知道的知识 如今写一下读取联系人数据相关操作 要读取通讯录数据库 须要 创建通讯录对象 查询获取数据(全部或者部分) 获取通讯录某一 ...

  4. iOS通讯录相关知识-浅析

    本文来自于:贞娃儿的博客  http://blog.sina.com.cn/zhenwawaer  在开发一些应用中,我们如果需要iPhone设备中的通讯录信息.或者,需要开发通讯录相关的一些功能.那 ...

  5. IOS 通讯录 (访问,添加,修改)

      如何访问用户的通讯录 在iOS中,有2个框架可以访问用户的通讯录 AddressBookUI.framework 提供了联系人列表界面.联系人详情界面.添加联系人界面等 一般用于选择联系人 Add ...

  6. IOS通讯录的隐藏标签【电话】的特殊功能(在IOS11已失效)

    这功能比较适合有强迫症,爱折腾的人哈!! 规范了通讯录标签,以后可以轻松的知道别人是用短号还是亲情网给你打电话. 如果是长号还可以显示归属地. 也许从IOS8(不太清楚)开始自带了号码归属地显示功能, ...

  7. iOS 通讯录编程【总结】

    第一大块儿:读取通讯录 1.iOS 6以上系统,争取获取用户允许: 初始化的时候须要推断.设备是否授权 -(id)init{ self = [super init]; [self createdABH ...

  8. iOS 通讯录基础

    iOS  6 之后应用訪问通讯录须要获得用户授权,而且仅仅授权一次,即使卸载了之后再安装.也不用再次授权. 开发通讯录应用须要两个框架: 1.ABAddressBook    主要用于提供訪问通讯录中 ...

  9. iOS通讯录整合,兼容iOS789写法,附demo

    苹果的通讯录功能在iOS7,iOS8,iOS9 都有着一定的不同,iOS7和8用的是 <AddressBookUI/AddressBookUI.h> ,但是两个系统版本的代理方法有一些变化 ...

随机推荐

  1. C++ Error C2662 cannot convert 'this' pointer from 'const *'

    ---恢复内容开始--- 这个错误在于一点:常量对象只能调用常量成员(函数\变量),不能调用非常量成员.另一方面,非常量对象,既可以调用常量成员,又可以调用非常量成员. class A { publi ...

  2. Django-Rest framework中文翻译-generic-views

    通用视图 Django的通用视图......被开发为常见用法模式的快捷方式......它们采用视图开发中的某些常见习语和模式并对其进行抽象,以便您可以快速编写数据的常用视图,而无需重复自己. - Dj ...

  3. MySQL 分库、分表

    Mysql Sharding 前言 1)Sharding是按照一定规则重新分布数据的方式 2)解决单机写入压力过大和容量问题 3)  解决单机查询慢的问题 4)本文主要根据用户登录场景分析 Shard ...

  4. java List 数组删除元素

    在 java 中,ArrayList 是一个很常用的类,在编程中经常要对 ArrayList 进行增.删.改.查操作.之前在学校时一直认为删除操作是最简单的,现在才越发觉得自己愚蠢.只需要设置好预期条 ...

  5. 【Codeforces 1102E】Monotonic Renumeration

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 会发现如果a[i]=a[j] 那么b[i]~b[j]都是相同的,等于b[i] 而b[i]等于b[i-1]+1或者b[i] 有两种可能 所以对于 ...

  6. [luoguP2158] [SDOI2008]仪仗队(数论)

    传送门 可以看出 (i, j) 能被看到,(i * k, j * k) 都会被挡住 暴力 所以 gcd(i, j) == 1 的话 ans ++ 那么可以枚举一半(中轴对称),求解答案,只能拿30分 ...

  7. noip模拟赛 兔子

    [问题描述]在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连.换句话讲,这些兔子窝 ...

  8. UVa - 12451 - Let's call SPaDe a SPaDe

    先上题目: Problem H: Let's call SPaDe a SPaDe Passing time, walking the passage, as you pass the String ...

  9. 小L 的二叉树(洛谷 U4727)

    题目背景 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣. 所以,小L当时卡在了二叉树. 题目描述 在计算机科学中,二叉树是每个结点最多有两个子结点的 ...

  10. vim中256色的配色表

    vim貌似支持的颜色很有限.white  black  yellow  cyan   magenta   blue   grey   green   red,大多数颜色前面都可以加light 或者 d ...