关于IOS获取本地通讯录信息(包含iOS9.0前后)
在ios开发当中,获取用户本地的通讯录功能愈加频繁的出现,七两自己也在自己公司的项目当中遇到的获取本地的通讯录信息的功能(俗称“种子用户功能”,太可怕了)。对此七两总结了自己使用本地通讯录时的注意点,希望对大家有所帮助。
首先对于获取本地通讯录的信息,大苹果在ios9.0之后推出了另外的一个使用方式(controller),类似于之前searchcontroller与searchBar,对此七两在此分成两部分,ios9.0前与ios9.0后两部分进行总结。
一、iOS9.0前
先附上七两自己写得代码:
对于苹果对于通讯录的操作实现可以类比sqlite与sqlite3的管理实现方式,及我们在使用通讯录时需调用类似于sqlite3的管理对象,对此七两自己习惯将对通讯录的操作过程写成单例,具体如下:
.h文件
[objc] view plaincopy
- #import <Foundation/Foundation.h>
- #import <AddressBook/AddressBook.h>
- #import <UIKit/UIKit.h>
- typedef void(^YFAddressBookBlock)(BOOL canRead, ABAuthorizationStatus authorStatus);
- @interface YFAddressBookManger : NSObject
- @property (nonatomic, assign) ABAddressBookRef addressBook;
- //单例类方法
- + (instancetype)shareManger;
- //设置传值
- - (void)canReadAddressBookWithBlock:(YFAddressBookBlock)block;
- - (void)gotoSetting:(UIViewController *)vc;
- @end
.m文件
[objc] view plaincopy
- #import "YFAddressBookManger.h"
- @implementation YFAddressBookManger
- + (instancetype)shareManger{
- static YFAddressBookManger *manger = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- if (!manger) {
- manger = [[YFAddressBookManger alloc]init];
- }
- });
- return manger;
- }
- - (id)init{
- self = [super init];
- if (self) {
- _addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
- }
- return self;
- }
- //获取读取权限
- - (void)canReadAddressBookWithBlock:(YFAddressBookBlock)block{
- ABAuthorizationStatus authStatus = ABAddressBookGetAuthorizationStatus();
- if (authStatus == kABAuthorizationStatusNotDetermined) {
- ABAddressBookRequestAccessWithCompletion(_addressBook, ^(bool granted, CFErrorRef error) {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (error) {
- //拒绝访问
- block(NO,kABAuthorizationStatusDenied);
- }else{
- block(YES,0);
- }
- });
- });
- }else if (authStatus == kABAuthorizationStatusAuthorized){
- block(YES,0);
- }else{
- block(NO,authStatus);
- }
- }
- //去设置页面
- - (void)gotoSetting:(UIViewController *)vc{
- NSString *appName = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleDisplayName"];
- if (!appName) appName = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleName"];
- NSString *message = [NSString stringWithFormat:@"请在%@的\"设置-隐私-通讯录\"选项中,\r允许%@访问你的通讯录。",[UIDevice currentDevice].model,appName];
- UIAlertController *alertVC = [[UIAlertController alloc]init];
- [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
- UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
- }];
- UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
- }];
- [alertVC addAction:cancleAction];
- [alertVC addAction:sureAction];
- }
- @end
后续引用通讯录中得数据至controller中的使用方式如下:
- #pragma mark - 获取本地的通讯录数据
- - (void)getDataSource{
- if (_dataSource == nil) {
- _dataSource = [NSMutableArray new];
- }
- [[YFAddressBookManger shareManger]canReadAddressBookWithBlock:^(BOOL canRead, ABAuthorizationStatus authorStatus) {
- if (canRead) {
- ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
- CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
- CFIndex num = ABAddressBookGetPersonCount(addressBook);
- for (NSInteger i = 0; i < num; i++) {
- ABRecordRef people = CFArrayGetValueAtIndex(allLinkPeople, i);
- ABMultiValueRef phones = ABRecordCopyValue(people, kABPersonPhoneProperty);
- for (int k = 0; k<ABMultiValueGetCount(phones); k++)
- {
- //获取該Label下的电话值
- NSString * personPhone = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phones, k);
- NSString *newP = [personPhone stringByReplacingOccurrencesOfString:@" " withString:@""];
- newP = [newP stringByReplacingOccurrencesOfString:@"-" withString:@""];
- // 去除+86
- if ([newP containsString:@"+86"]) {
- newP = [newP stringByReplacingOccurrencesOfString:@"+86" withString:@""];
- }
- // 去除+
- if ([newP containsString:@"+"]) {
- newP = [newP stringByReplacingOccurrencesOfString:@"+" withString:@""];
- }
- if (![_dataSource containsObject:newP]) {
- [_dataSource addObject:newP];
- }
- }
- }
- }else{
- [[YFAddressBookManger shareManger] gotoSetting:self];
- }
- }];
- }
如果需要其余的多余的单值属性需不同的字段,代码中的ABRecordCopyValue方法可以理解为C语言中得字典。即可根据不同的单值属性获取。
二、iOS9.0之后
苹果推荐ContactsUI使用,具体的使用方式如下:
- pragma mark - <CNContactPickerViewController代理方法>
- /* 当选中一个联系人时,会执行该方法
- @param picker 选择联系人的控制器
- @param contact 选择的联系人 /
- (void)contactPicker:(CNContactPickerViewController )picker didSelectContact:(CNContact )contact{
- // 1.获取联系人的姓名 NSString *firstName = contact.givenName;
- NSString *lastName = contact.familyName;
- NSLog(@"%@ %@", firstName, lastName);
- // 2.获取联系人的电话号码 NSArray *phoneNumers = contact.phoneNumbers;
- for (CNLabeledValue *labelValue in phoneNumers) {
- CNPhoneNumber *phoneNumber = labelValue.value;
- NSString *phoneValue = phoneNumber.stringValue;
- NSString *phoneLabel = labelValue.label;
- NSLog(@"%@ %@", phoneValue, phoneLabel);
- }
- }
- /* 当选中某一个联系人的某一个属性时,会执行该方法
- @param contactProperty 选中的联系人属性
- */
- (void)contactPicker:(CNContactPickerViewController )picker didSelectContactProperty:(CNContactProperty )contactProperty{}
具体的细节使用如下:
- // 1.获取授权状态
- CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
- // 2.如果不是已经授权,则直接返回
- if (status != CNAuthorizationStatusAuthorized) return;
- // 3.获取联系人
- // 3.1.创建联系人仓库
- CNContactStore *store = [[CNContactStore alloc] init];
- // 3.2.创建联系人的请求对象
- // keys决定这次要获取哪些信息,比如姓名/电话
- NSArray *fetchKeys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
- CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:fetchKeys];
- // 3.3.请求联系人
- NSError *error = nil;
- [store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOLBOOL * _Nonnull stop) {
- // stop是决定是否要停止
- // 1.获取姓名
- NSString *firstname = contact.givenName;
- NSString *lastname = contact.familyName;
- NSLog(@"%@ %@", firstname, lastname);
- // 2.获取电话号码
- NSArray *phones = contact.phoneNumbers;
- // 3.遍历电话号码
- for (CNLabeledValue *labelValue in phones) {
- CNPhoneNumber *phoneNumber = labelValue.value;
- NSLog(@"%@ %@", phoneNumber.stringValue, labelValue.label);
- }
- }];
关于IOS获取本地通讯录信息(包含iOS9.0前后)相关推荐
- IOS获取系统通讯录联系人信息
2019独角兽企业重金招聘Python工程师标准>>> IOS获取系统通讯录联系人信息 一.权限注册 随着apple对用户隐私的越来越重视,IOS系统的权限设置也更加严格,在获取系统 ...
- QT获取本地网络信息
QT获取本地网络信息 开发工具与关键技术:QtCreator.C++ 作者:何任贤 撰写时间:2020年06月10日 获取本机网络信息要在工程文件(.Pro)加上 QT += network 然后就是 ...
- Python time 获取本地时间戳(包含毫秒)
Python time 获取本地时间戳(包含毫秒) #!/usr/bin/python # -*- coding: UTF-8 -*- import timedef get_current_time( ...
- 如何获取本地时间信息,并把getDay()函数获取到的日期改为日一二三四五六
如何获取本地时间信息,并把getDay()函数获取到的日期改为日一二三四五六 <!DOCTYPE html> <html><head><meta charse ...
- iOS 获取本地相册图片或视频
1.先判断iOS 相机相册的权限检测 相关链接 https://www.jianshu.com/p/8a944534e0ee 2.iOS 获取本地相册图片 iOS 获取本地相册图片一 iOS 获取本地 ...
- ios获取区域服务器信息,ios获取服务器数据
ios获取服务器数据 内容精选 换一换 调用API出错后,将不会返回结果数据.调用方可根据每个API对应的错误码来定位错误原因.当调用出错时,HTTP请求返回一个4xx或5xx的HTTP状态码.返回的 ...
- iOS获取WIFI配置信息,WIFI名称、网关(路由器地址)、本机IP地址、DNS
DEMO地址(看代码,什么就都有了):https://github.com/SimpleBraver/test_wifi.git 1.获取当前手机WIFI名称信息 #import <System ...
- ios实现本地通讯录点击(标识)跳转APP
第一次接触这个功能是因为全能名片王,在把创建的联系人导入通讯录的时候会看到在本地通讯录页面会有一个全能名片王的标识符,点击以后会跳转到全能名片王的app,号酷炫有没有.于是就自然而然的百度了下这个功能 ...
- ios 获取本地音乐
给大家分享一个获取ios本地音乐的办法. 首先要引入这两个类库 然后这就是获取本地音乐的代码 可以看到下面的这个属性MPMediaItemPropertyAssetURL 是获取本地音乐的url 的 ...
最新文章
- OpenCV(五)绘制图形与文本
- 做出仿iphone的圆角效果,以及shpe的各个属性
- 聚集索引和非聚集索引实例
- 百练OJ:2767:简单密码
- Jenkins 基础入门
- 值得收藏的时间复杂度速查表:数据结构操作、排序算法、图操作、堆操作
- C语言项目:灰度处理技术
- 架构设计中的方法学(七)
- zookeeper 单机和集群搭建(windows环境+linux环境)
- 使用Jenkins容器构建时,关于maven项目settings.xml的位置
- linux grub 删除文件,删除grub的方法(转)
- 红帽linux挂载光盘_redhat挂载光盘 命令 - 卡饭网
- kubernetes lowB安装方式
- 2022年4月23日美团笔试
- 插曲(1)dht11的连接
- 简单有趣,半小时漫画中国史
- SSIS_创建SSIS包和数据源
- cesium加载谷歌影像底图
- linux上好玩的东西
- 2019/7/2 图书馆检索·真·简陋版(新人学习向)
热门文章
- AWS攻略——使用CodeCommit托管代码
- 使用windbg抓取崩溃文件和分析的过程
- C++中标准模板库std::pair的实现
- windows7 64位机上CUDA7.0配置及在VS2010中的简单使用举例
- OpenCV中resize函数五种插值算法的实现过程
- 【Python】解决print不能立即打印的问题
- Travis CI : 最小的分布式系统(二)
- 男孩子学计算机和学医哪个好,你认为学医好还是读211大学的电子信息好?
- 卡顿严重_魔兽怀旧服:安其拉开门二测结果出炉,暴雪依然无法解决卡顿问题...
- axure中图表背影_Axure 教程:动态图表——排名图