在早些时候,当iOS 6还没出来,我们访问通讯录只要如下简单的代码:

ABAddressBookRef addressBook = ABAddressBookCreate();

不过 在iOS 6上,这个API返回空值。苹果提供了如下API:

// Call ABAddressBookCreateWithOptions to create an instance of AddressBook. The
// ABAddressBookRef will initially not have access to contact data. The app must
// then call ABAddressBookRequestAccessWithCompletion to request this access.
// The options argument is reserved for future use. Currently it will always be NULL.
// If access to contact data is already restricted or denied, this will fail returning
// a NULL ABAddressBookRef with error kABOperationNotPermittedByUserError.
AB_EXTERN ABAddressBookRef ABAddressBookCreateWithOptions(CFDictionaryRef options, CFErrorRef* error) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);

由于之前的iOS 版本在隐私方面被人诟病,以至于出现App在没有提醒用户的情况访问通讯录而被拒绝的案例。现在每个App要访问通讯录都应该得到用户的授权:

因此,如上注释所描述的,我们应该调用如下API来获取授权:

// Users are able to grant or deny access to contact data on a per-app basis. To request
// access to contact data, call ABAddressBookRequestAccessWithCompletion. This will not
// block the app while the user is being asked to grant or deny access. Until access has
// been granted, a non-NULL ABAddressBookRef will not contain any contacts and any attempt to
// modify contacts will fail with CFErrorRef returning kABOperationNotPermittedByUserError.
// The user will only be prompted the first time access is requested; any subsequent calls
// to ABAddressBookCreateWithOptions will use the existing permissions. The completion
// handler is called on an arbitrary queue. If the ABAddressBookRef is used throughout the app,
// then all usage should be dispatched to the same queue to use ABAddressBookRef in a
// thread-safe manner.
typedef void(^ABAddressBookRequestAccessCompletionHandler)(bool granted, CFErrorRef error);
AB_EXTERN void ABAddressBookRequestAccessWithCompletion(ABAddressBookRef addressBook,  ABAddressBookRequestAccessCompletionHandler completion) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);
    ABAddressBookRef addressBook = NULL;__block BOOL accessGranted = NO;if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6dispatch_semaphore_t sema = dispatch_semaphore_create(0);ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {accessGranted = granted;dispatch_semaphore_signal(sema);});dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);dispatch_release(sema);}else { // we're on iOS 5 or olderaccessGranted = YES;}if (accessGranted) {// Do whatever you want here.}

不过这只会在第一次请求授权时才显示对话框,如果用户已经拒绝了,我们可以判断下授权状态:

// To check the app's access to contact data. Based upon the access, the app could
// display or hide its UI elements that would access any AddressBook API.
//
// kABAuthorizationStatusNotDetermined
// The user has not yet made a choice regarding whether this app can access the data class.
//
// kABAuthorizationStatusRestricted
// This application is not authorized to access the data class. The user cannot change
// this application’s status, possibly due to active restrictions such as parental controls
// being in place.
//
// kABAuthorizationStatusDenied
// The user explicitly denied access to the data class for this application.
//
// kABAuthorizationStatusAuthorized
// This application is authorized to access the data class.
//
typedef CF_ENUM(CFIndex, ABAuthorizationStatus) {kABAuthorizationStatusNotDetermined = 0,kABAuthorizationStatusRestricted,kABAuthorizationStatusDenied,kABAuthorizationStatusAuthorized
};
AB_EXTERN ABAuthorizationStatus ABAddressBookGetAuthorizationStatus(void) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);

通过判断授权状态,我们可以再次提醒用户进行授权。

比较糟糕的是,在中文版上,访问通讯录会出现汉化错误,XXX 想访问您的日历:

从上图中可以看到,微信还给了用户更为详细的信息,表示现在是要访问通讯录,而非日历。

于是,我在上面提到的代码中翻了几遍,都没找到设置alertView详细信息的地方,最后在SO上得到解答 —— 通过在plist设置NSContactsUsageDescription关键字。详细文档见此。

关于iOS系统中通讯录的访问相关推荐

  1. iOS系统中应用程序间通信的方法及装置

    申请号 :CN 201210548391 申请时间 : 2101.12.17 申请人 : 北京奇虎科技有限公司 [摘要] 本发明公开了iOS系统中应用程序间通信的方法及装置,用于在当前应用程序与目标应 ...

  2. 深入理解HTTPS及在iOS系统中适配HTTPS类型网络请求(上)

    2019独角兽企业重金招聘Python工程师标准>>> 深入理解HTTPS及在iOS系统中适配HTTPS类型网络请求 一.引言 本篇博客主要讨论如何在客户端与服务端之间进行HTTPS ...

  3. 在MacOS和iOS系统中使用OpenCV

    在MacOS和iOS系统中使用OpenCV 前言 OpenCV 是一个开源的跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法. 最近试着在 MacOS 和 iOS 上使用 OpenCV ...

  4. vue单应用在ios系统中实现微信分享功能

    表示是第一次使用vue做单应用显目,也是在逐渐的摸索中~更是各种踩坑,各种填坑,打算写博客么?是因为不想写笔记了,嗯嗯 就是这么简单 进入正题. 刚开始做微信分享的这个功能的时候,脑补了官方文档微信J ...

  5. 解决Android软键盘弹出覆盖h5页面输入框问题 // 在ios系统中输入框软键盘消失后,页面不回弹的问题 // 解决苹果不回弹页面 // 微信环境打开

    //解决Android软键盘弹出覆盖h5页面输入框问题 window.addEventListener('resize', () => {if (document.activeElement.t ...

  6. iPhone iOS 系统中 设置-开发者 对应的翻译

    iOS 系统中 设置开发者对应的翻译 ------ 第一屏 第二屏 第三屏 针对网络差的调试, 模拟网络特别慢的环境 原文链接 https://www.jianshu.com/p/55ec0d466f ...

  7. iOS系统中导航栏的转场解决方案与最佳实践

    背景 目前,开源社区和业界内已经存在一些 iOS 导航栏转场的解决方案,但对于历史包袱沉重的美团 App 而言,这些解决方案并不完美.有的方案不能满足复杂的页面跳转场景,有的方案迁移成本较大,为此我们 ...

  8. IOS系统中H5页面实现摇一摇功能

    公司准备开年会了,年会活动用了一套别人的系统,根据测试,有些游戏的摇一摇功能在IOS上无法使用,为了修复该功能,踩了一些坑,特此记录如下: 1. 因为IOS系统的安全要求,项目必须是在https的域名 ...

  9. IOS系统中input标签获取焦点页面会放大的问题

    IOS系统中input标签获取焦点页面会放大的问题 在iOS系统中打开网页,input框输入时,输入框获取焦点的时候页面会放大,如果没有经过设置,页面放大之后就不会自动还原.使内容撑开浏览器,底部产生 ...

最新文章

  1. 使用cat /proc/进程id/maps 查看进程内存映射
  2. WPF自定义空心文字
  3. Wisdom RESTClient支持自动化测试并可以生成API文档
  4. Spring Security Architecture--官方
  5. tomcat8启动慢
  6. 终结“永恒之蓝”后,再战“永恒之黑”
  7. php iframe 上传文件,php+iframe 实现上传文件功能示例
  8. 一辆车,一年大概要花费多少钱,除了油费?
  9. 【Luogu1095】守望者的逃离
  10. mysql的server_id怎么设置_MySQL Server-id踩到的坑
  11. 编程精华资源(ITeye优秀专栏)大汇总
  12. 如何判断行业和公司的「钱途」
  13. 三门峡市新型智慧城市顶层设计方案通过专家评审
  14. 使用股指期货与ETF基金进行期现套利
  15. Matlab建的模型如何导入MS中,lammps输出的模型如何导入MS中建模
  16. error: failed to push some refs to如何解决
  17. 怎么用python编写个apk_【android】如何利用python做Android项目自动化构建,并一键实现构建结果发送到钉钉通知以及通过二维码下载apk或者其他处理等功能...
  18. 大数据必学Java知识(一):Java基础入门语法和安装
  19. ssh远程连接服务器
  20. 【笔记】OpenSSL 使用

热门文章

  1. 3.26期货每日早盘操作建议
  2. Unity3d基础学习第13天
  3. JavaScript语句结尾的;加不加
  4. 参考别人的面试总结:linux C/C++服务器后台开发面试题总结
  5. Navicat Premium 12下载破解
  6. Fomo3D游戏前景
  7. Scapy介绍官方文档翻译
  8. webpack 优化启动项目速度
  9. CAN-bus收发器TJA1040T典型接法
  10. 左程云——归并排序和快速排序