最新消息:20181230 VPS服务器已从Linode换到腾讯云香港,主题仍用朋友推荐的大前端D8

[规避解决]swift中通过CNContactStore获取联系人列表出错:error=Error Domain=CNErrorDomain Code=100访问被拒绝

Swift crifan 893浏览 0评论

折腾:

[规避解决]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 处理图片的一些小 Tip

找不到问题根本原因。

去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(_ entityTypeCNEntityType,

              completionHandler completionHandler: (Bool,

                                         NSError?) -> Void)

Parameters

entityType
Set to CNEntityTypeContacts.
completionHandler
Set granted to YES if the user allows access and error is nil.

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

iOS 9 by Tutorials 笔记(十二)

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真机

均无法弹出授权对话框

正常的话,应该是:

http://devstreaming.apple.com/videos/wwdc/2015/223rmo6dv9hxh/223/223_introducing_the_contacts_framework_for_ios_and_os_x.pdf

中这种:

OS X + iOS + appleWatch

网友也遇到类似问题。

并且Mac版 OS X10.11也出现类似问题-》但是人家在新版的10.11中又解决了该问题了。。

暂时只有一个人是通过删除了info.plist再重建而不知道如何就解决了问题

我此处试了,没有解决。

暂时也找不到其它解决或规避的办法。。。

注:

官网稳定:

http://devstreaming.apple.com/videos/wwdc/2015/223rmo6dv9hxh/223/223_introducing_the_contacts_framework_for_ios_and_os_x.pdf

倒是解释的不错。

算了,打算去尝试:

[已解决]尝试用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

Request Access Permission to Contacts Programmatically | Requesting Access Permission to Address Book in iOS | iOS SDK Guide | iOS Programming

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访问被拒绝

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
63 queries in 0.114 seconds, using 10.02MB memory