一、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. luogu P3899 [湖南集训]谈笑风生 线段树合并

    Code: #include<bits/stdc++.h> #define maxn 300002 #define ll long long using namespace std; vo ...

  2. docker 1-->docker compose 转载

    转自:http://www.ityouknow.com/docker/2018/03/22/docker-compose.html Docker-Compose 是 Docker 的一种编排服务,是一 ...

  3. 带返回值的线程Callable

  4. 这份Koa的简易Router手敲指南请收下

    上一期链接--也就是本文的基础,参考KOA,5步手写一款粗糙的web框架 本文参考仓库:点我 Router其实就是路径匹配,通过匹配路径,返回给用户相应的网站内容. 以下方例子为例,主要通过提取req ...

  5. vue-cli 3.x 配置多环境

    思路:新建一个 process.env 变量. 把 webpack 配置放到 vue.config.js 里面. 如果根目录下没有该文件,新建.配置参考:https://cli.vuejs.org/z ...

  6. led1,1s取反,led2计数10次取反

    1 //利用定时器0 1s,led1取反,利用计数器1,跳10,取反 #include<reg52.h> #define uchar unsigned char #define uint ...

  7. hdu 5122(2014ACM/ICPC亚洲区北京站) K题 K.Bro Sorting

    传送门 对于错想成lis的解法,提供一组反例 1 3 4 2 5同时对于这次案例也可以观察出解法:对于每一个数,如果存在比它小的数在它后面,它势必需要移动,因为只能小的数无法向右移动,而且每一次移动都 ...

  8. java Beanutils.copyProperties( )用法

    这是一篇开发自辩甩锅稿~~~~ 昨天测试小姐姐将我的一个bug单重开了,emmmm....内心OS:就调整下对象某个属性类型这么简单的操作,我怎么可能会出错呢,一定不是我的锅!!but再怎么抗拒,bu ...

  9. 1. Jenkins 入门使用

    1. 下载jenkins https://pkg.jenkins.io/redhat-stable/ sudo wget -O /etc/yum.repos.d/jenkins.repo https: ...

  10. 【01】CSS制作的图形

    [01]CSS制作的图形   绘制五角星:   通过border绘制三角形.然后通过transfrom来旋转35度. 绘制对称的图形,最后绘制顶部的三角形即可.   元素本身,加上:before和:a ...