请求访问Swift 3中的联系人



我想访问用户的联系人,并打算使用Apple提供的联系人和联系人框架。

首先,我需要征求权限以访问用户的联系人,并且难以这样做。在Swift 2中,人们可以要求这样的许可:

func requestForAccess(completionHandler: (accessGranted: Bool) -> Void) {
    let authorizationStatus = CNContactStore.authorizationStatusForEntityType(CNEntityType.Contacts)
    switch authorizationStatus {
    case .Authorized:
        completionHandler(accessGranted: true)
    case .Denied, .NotDetermined:
        self.contactStore.requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (access, accessError) -> Void in
            if access {
                completionHandler(accessGranted: access)
            }
            else {
                if authorizationStatus == CNAuthorizationStatus.Denied {
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in 
                        let message = "(accessError!.localizedDescription)nnPlease allow the app to access your contacts through the Settings."
                        self.showMessage(message)
                    })
                }
            }
        })
    default:
        completionHandler(accessGranted: false)
    }
}

我试图像这样将其转换为Swift 3,但仍提出错误。错误是"实例成员'async'不能在类型的'dispatchqueue'上使用;您的意思是使用这种类型的值吗?":

func requestForAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void) {
    let authorizationStatus = CNContactStore.authorizationStatus(for: CNEntityType.contacts)
    switch authorizationStatus {
    case .authorized:
        completionHandler(true)
    case .denied, .notDetermined:
        self.contactStore.requestAccess(for: CNEntityType.contacts, completionHandler: { (access, accessError) -> Void in
            if access {
                completionHandler(access)
            }
            else {
                if authorizationStatus == CNAuthorizationStatus.denied {
                    DispatchQueue.async(group: DispatchQueue.main, execute: { () -> Void in //error here
                        let message = "(accessError!.localizedDescription)nnPlease allow the app to access your contacts through the Settings."
                        self.showMessage(message)
                    })
                }
            }
        })
    default:
        completionHandler(false)
    }
}

任何人可以帮助尝试解决这个问题吗?任何帮助将不胜感激。提前一吨。

欢呼,theo

而不是

DispatchQueue.async(group: DispatchQueue.main, execute: { ... }

DispatchQueue.main.async { ... }

顺便说一句,如果以前已拒绝了权限,则再次请求授权是没有意义的,因为OS不会向最终用户提供任何"授予访问" UI。仅当用户以前没有拒绝访问时才这样做。

如果对该应用程序成功操作确实至关重要,则可以向他们展示一个警报,使他们可以直接从您的应用程序进行设置:

func requestAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void) {
    switch CNContactStore.authorizationStatus(for: .contacts) {
    case .authorized:
        completionHandler(true)
    case .denied:
        showSettingsAlert(completionHandler)
    case .restricted, .notDetermined:
        store.requestAccess(for: .contacts) { granted, error in
            if granted {
                completionHandler(true)
            } else {
                DispatchQueue.main.async {
                    self.showSettingsAlert(completionHandler)
                }
            }
        }
    }
}
private func showSettingsAlert(_ completionHandler: @escaping (_ accessGranted: Bool) -> Void) {
    let alert = UIAlertController(title: nil, message: "This app requires access to Contacts to proceed. Go to Settings to grant access.", preferredStyle: .alert)
    if
        let settings = URL(string: UIApplication.openSettingsURLString),
        UIApplication.shared.canOpenURL(settings) { 
            alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { action in
                completionHandler(false)
                UIApplication.shared.open(settings)
            })
    }
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { action in
        completionHandler(false)
    })
    present(alert, animated: true)
}

同样的事情,但它将否视为 no ,而不是现在或类似的东西。您在Apple隐私提示中看到了任何模糊逻辑吗?我没有。

fileprivate func requestForAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void) {
    let authorizationStatus = CNContactStore.authorizationStatus(for: CNEntityType.contacts)
    switch authorizationStatus {
    case .authorized:
        completionHandler(true)
    case .notDetermined:
        self.contactStore.requestAccess(for: CNEntityType.contacts, completionHandler: { (access, accessError) -> Void in
            if access {
                completionHandler(access)
            }
            else {
                completionHandler(false)
            }
        })
    default:
        completionHandler(false)
    }
}

最新更新