[英]Request Access To Contacts in Swift 3
我想訪問用戶的聯系人,並計划使用 Apple 提供的聯系人和 ContactsUI 框架來訪問。
不過,首先,我需要請求訪問用戶聯系人的權限,但這樣做時遇到了問題。 在 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)\n\nPlease 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)\n\nPlease allow the app to access your contacts through the Settings."
self.showMessage(message)
})
}
}
})
default:
completionHandler(false)
}
}
任何人都可以幫忙解決這個問題嗎? 任何幫助將不勝感激。 提前致謝。
干杯,西奧
而不是
DispatchQueue.async(group: DispatchQueue.main, execute: { ... }
做
DispatchQueue.main.async { ... }
順便說一下,如果之前的權限被拒絕,那么再次請求授權是沒有意義的,因為操作系統不會向最終用戶提供任何“授予訪問權限”的 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 視為no ,而不是可能,不是 now 或類似的東西。 你看到蘋果隱私提示中有什么模糊的邏輯嗎? 我沒有。
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)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.