折腾:
[规避解决]swift中通过新接口CNContactStore去获取地址簿联系人列表
期间,用代码:
if #available(iOS 9.0, *) { let store = CNContactStore() print("store=\(store)") do{ // let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey]) let keysToFetch = [CNContactEmailAddressesKey, CNContactGivenNameKey, CNContactPhoneNumbersKey] print("keysToFetch=\(keysToFetch)") //keysToFetch=["emailAddresses", "givenName", "phoneNumbers"] let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName(""), keysToFetch: keysToFetch) print("contacts=\(contacts)") for (curIdx, eachContact) in contacts.enumerate() { print("[\(curIdx)] \(eachContact)") } } catch let error{ print("error=\(error)") //error=Error Domain=CNErrorDomain Code=100 "访问被拒绝" UserInfo={NSLocalizedDescription=访问被拒绝, NSLocalizedFailureReason=此应用尚未获得访问“通讯录”的许可。} } } else { // Fallback on earlier versions print("current OS version is <= 9.0") } |
结果出错:
error=Error Domain=CNErrorDomain Code=100 "访问被拒绝" UserInfo={NSLocalizedDescription=访问被拒绝, NSLocalizedFailureReason=此应用尚未获得访问“通讯录”的许可。}
搜:
swift CNContactStore error Domain CNErrorDomain Code 100
Always get CNErrorDomain code=100 | Apple Developer Forums
需要先去调用:
CNContactStore.authorizationStatusForEntityType
uitableview – How to load all contacts in an array ios9 – Stack Overflow
ios – how to fetch contact image and phone Number in my app using Objective C – Stack Overflow
objective c – Issue about the newest Contacts ios Framework – Stack Overflow
func readPhoneContactToList(){ print("readPhoneContactToList") if #available(iOS 9.0, *) { let contactStore = CNContactStore() print("contactStore=\(contactStore)") //<CNDataMapperContactStore: 0x79e41eb0> let authStatus:CNAuthorizationStatus = CNContactStore.authorizationStatusForEntityType(CNEntityType.Contacts) print("authStatus=\(authStatus)") //CNAuthorizationStatus switch authStatus { case CNAuthorizationStatus.Denied, CNAuthorizationStatus.Restricted: let noAuthAlertController = UIAlertController(title: "没有操作联系人的权限!", message: nil, preferredStyle: UIAlertControllerStyle.Alert) let sureAlertAction = UIAlertAction(title: "确定", style: UIAlertActionStyle.Destructive, handler: nil) noAuthAlertController.addAction(sureAlertAction) self.presentViewController(noAuthAlertController, animated: true, completion: nil) return case CNAuthorizationStatus.NotDetermined: contactStore.requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (granted, error) -> Void in print("granted=\(granted)") //false if granted { self.readPhoneContact(contactStore) }else{ let noAuthAlertController = UIAlertController(title: "您没有同意授权操作联系人!", message: nil, preferredStyle: UIAlertControllerStyle.Alert) let sureAlertAction = UIAlertAction(title: "确定", style: UIAlertActionStyle.Destructive, handler: nil) noAuthAlertController.addAction(sureAlertAction) self.presentViewController(noAuthAlertController, animated: true, completion: nil) } }) case CNAuthorizationStatus.Authorized: readPhoneContact(contactStore) } } else { // Fallback on earlier versions print("current OS version is <= 9.0") } } @available(iOS 9.0, *) func readPhoneContact(contactStore:CNContactStore){ do{ // let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey]) let keysToFetch = [CNContactEmailAddressesKey, CNContactGivenNameKey, CNContactPhoneNumbersKey] print("keysToFetch=\(keysToFetch)") //keysToFetch=["emailAddresses", "givenName", "phoneNumbers"] let contacts = try contactStore.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName(""), keysToFetch: keysToFetch) print("contacts=\(contacts)") for (curIdx, eachContact) in contacts.enumerate() { print("[\(curIdx)] \(eachContact)") } } catch let error{ print("error=\(error)") //error=Error Domain=CNErrorDomain Code=100 "访问被拒绝" UserInfo={NSLocalizedDescription=访问被拒绝, NSLocalizedFailureReason=此应用尚未获得访问“通讯录”的许可。} } } |
结果还是不行。
直接就执行到了:NotDetermined
然后也没有弹出让用户同意权限的弹窗。
搜:
swift CNContactStore error Domain KCLErrorDomain Code 100
swift CNContactStore 访问被拒绝
swift CNContactStore access denied
初窥iOS 9联系人框架 – CocoaChina_让移动开发更简单
A First Look at Contacts Framework in iOS 9 | Swift Tutorial
CNContactStore Class Reference
MyContacts-Swift/ViewController.swift at master · ooper-shlab/MyContacts-Swift · GitHub
此处,我的代码,貌似没问题。
搜:
swift CNContactStore requestAccessForEntityType not work
swift requestAccessForEntityType not work
swift – CNContactStore.requestAccessForEntityType argument issue – Stack Overflow
swift requestAccessForEntityType not show
swift requestAccessForEntityType error 100
ios访问手机通讯录获取联系人手机号 – Android移动开发知识分享 – 时刻知(ShiKeZhi)
找不到问题根本原因。
去iOS真机上运行试试
结果真机上问题同样:
readPhoneContactToList contactStore=<CNDataMapperContactStore: 0x15dc4a560> authStatus=CNAuthorizationStatus granted=false, error=Optional(Error Domain=CNErrorDomain Code=100 "访问被拒绝" UserInfo={NSLocalizedDescription=访问被拒绝, NSLocalizedFailureReason=此应用尚未获得访问“通讯录”的许可。}) |
去iPhone的设置界面中,看看能否找到这个通讯录的权限设置。
然后对于iOS模拟器:
然后里面是空的:
没有列出当前自己的程序。
难道是需要:
安装程序,调试程序之前,需要主动在app的配置里面配置是要求访问对应通讯录的权限?
搜:
swift CNContactStore wrapper
CNContactStore Class Reference
“
requestAccessForEntityType(_:completionHandler:)
Requests access to the user’s contacts.
Declaration
SWIFT
func requestAccessForEntityType(_ entityType: CNEntityType,
completionHandler completionHandler: (Bool,
Parameters
entityType | Set to CNEntityTypeContacts. |
completionHandler |
Discussion
Users are able to grant or deny access to contact data on a per-application basis. Request access to contact data by calling requestAccessForEntityType:completionHandler: method. This will not block your application while the user is being asked for permission. The user will only be prompted the first time access is requested; any subsequent CNContactStore calls will use the existing permissions. The completion handler is called on an arbitrary queue. It is recommended that you use CNContactStore instance methods in this completion handler instead of the UI main thread. This method is optional when CNContactStore is used in the background thread. If this method is not used, CNContactStore may block your application while the user is asked for access permission.
”
swift CNContactStore requestAccessForEntityType
Uppercase all contacts family names · GitHub
iOS-9-Sampler/ContactsViewController.swift at master · shu223/iOS-9-Sampler · GitHub
换成:
// contactStore.requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (granted, error) -> Void in CNContactStore().requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (granted, error) -> Void in |
还是不行。
换个UI界面里面去处理,看看是否有变化。
结果还是没用。
Programming iOS 9: Dive Deep into Views, View Controllers, and Frameworks – Matt Neuburg – Google 图书
去看看那个:
info.plist
Privacy – Contacts Usage Description
NSContactUsageDescription
结果问题依旧。。。
期间,几次都遇到了:
[已解决]swift调用CNContactStore的requestAccessForEntityType时出错:This application is modifying the autolayout engine from a background thread
通过:
dispatch_async(dispatch_get_main_queue(), { () -> Void in }) |
虽然解决了上述问题,但是此处问题依旧:
readPhoneContactToList contactStore=<CNDataMapperContactStore: 0x7afb78b0> authStatus=CNAuthorizationStatus granted=false, error=Optional(Error Domain=CNErrorDomain Code=100 "访问被拒绝" UserInfo={NSLocalizedDescription=访问被拒绝, NSLocalizedFailureReason=此应用尚未获得访问“通讯录”的许可。}) |
还是没有解决。
swift CNContactStore requestAccessForEntityType
Contacts Framework in Swift 2.0
Contacts.framework iOS9新的类,用来替代AddressBook – BrotherWay – 博客园
iOS9 之 Contacts – iOS菜鸟的成长之路 – SegmentFault
swift requestAccessForEntityType access contact now show
算了,再去iPhone真机上去试试
问题依旧。。。
并且,第二次再进入此处代码,结果会执行到:
case CNAuthorizationStatus.Denied, CNAuthorizationStatus.Restricted:
很明显是:
之前第一次,在没有弹出授权窗口的情况下,就不知道为何,返回false,没有授权
导致之后都是使用第一次的权限:没有授权了。。。
重置一下iOS模拟器试试
没用。
swift requestAccessForEntityType not granted for contact
ios – CNContactPicker grant permission not prompting – Stack Overflow
难道是:
像上面帖子说的,没有弹出授权对话框,也可以继续使用???
但是我此处,的确是:
没有授权,是没法访问的啊:
即使granted=false也去调用:
do{ // let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey]) let keysToFetch = [CNContactEmailAddressesKey, CNContactGivenNameKey, CNContactPhoneNumbersKey] print("keysToFetch=\(keysToFetch)") //keysToFetch=["emailAddresses", "givenName", "phoneNumbers"] let contacts = try contactStore.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName(""), keysToFetch: keysToFetch) print("contacts=\(contacts)") for (curIdx, eachContact) in contacts.enumerate() { print("[\(curIdx)] \(eachContact)") } } catch let error{ print("error=\(error)") //error=Error Domain=CNErrorDomain Code=100 "访问被拒绝" UserInfo={NSLocalizedDescription=访问被拒绝, NSLocalizedFailureReason=此应用尚未获得访问“通讯录”的许可。} } |
会出错:
keysToFetch=["emailAddresses", "givenName", "phoneNumbers"] error=Error Domain=CNErrorDomain Code=100 "访问被拒绝" UserInfo={NSLocalizedDescription=访问被拒绝, NSLocalizedFailureReason=此应用尚未获得访问“通讯录”的许可。} |
要不抽空试试去用:
CNContactPickerViewController
从而绕过授权弹窗的限制??
ios – How to retrieve emails from iPhone Contacts using swift? – Stack Overflow
流行的请求访问联系人没有显示ios9 – Pop for request access to contacts not show ios 9IT怪 挨踢怪 28印象 二八印象
->
Pop for request access to contacts not show ios 9 – Stack Overflow
这人遇到和我同样的问题。。。
此处的英文错误信息是:
_userInfo: { NSLocalizedDescription = "Access Denied"; NSLocalizedFailureReason = "This application has not been granted permission to access Contacts."; } |
那人删除了info.plist,重新建了一个,好像就可以了。
我也去试试。
我这里,不行。
swift contact info.plist
ios info.plist contact related
ObjC casting a block with toll-free-bridged types
CNContactPicker grant permission not prompting
swift requestAccessForEntityType popup
osx – CNContact for Mac OS X 10.11 – StackOverflow
[总结]
至此,基本上确定,这是个bug:
当前测试环境:
Mac
中的iOS 模拟器 9.2 iPhone5/6
iPhone 6真机
均无法弹出授权对话框
正常的话,应该是:
中这种:
OS X + iOS + appleWatch
网友也遇到类似问题。
并且Mac版 OS X10.11也出现类似问题-》但是人家在新版的10.11中又解决了该问题了。。
暂时只有一个人是通过删除了info.plist再重建而不知道如何就解决了问题
我此处试了,没有解决。
暂时也找不到其它解决或规避的办法。。。
注:
官网稳定:
倒是解释的不错。
算了,打算去尝试:
[已解决]尝试用CNContactPickerViewController去绕开权限bug而直接访问通讯录
再去试试:
swift Access Denied This application has not been granted permission to access Contacts
swift not been granted permission to access Contacts
swift CNContactStore Code 100 Access Denied not been granted permission to access Contacts
swift CNContactStore Code 100 Access Denied
iphone – Programmatically Request Access to Contacts – Stack Overflow
Always get CNErrorDomain code=100 | Apple Developer Forums
Contacts 框架 获取权限问题 | iOS开发 – CocoaChina CocoaChina_让移动开发更简单
也遇到同样问题了。。。
“我也遇到这种问题,而且即使第一次运行也没有弹出权限提示框。软件的状态一直为CNAuthorizationStatusNotDetermined,代码申请访问联系人信息时直接就被系统设置为CNAuthorizationStatusDenied了。再次运行又变为CNAuthorizationStatusNotDetermined。手机Privary-Contacts里面也没有我的软件在等待设置权限。好奇怪。 ”
swift CNContactStore Access Denied
还是无解。。。
转载请注明:在路上 » [规避解决]swift中通过CNContactStore获取联系人列表出错:error=Error Domain=CNErrorDomain Code=100访问被拒绝