Запрос доступа к контактам в Swift 3
Я хочу получить доступ к контактам пользователя и планирую сделать это, используя контакты и contactsui framework, которые поставляет 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)
}
}
кто-нибудь может помочь, чтобы попытаться исправить это? Любая помощь будет очень ценится. Спасибо заранее.
Ура, Тео!--3-->
1 ответов
вместо
DispatchQueue.async(group: DispatchQueue.main, execute: { ... }
do
DispatchQueue.main.async { ... }
кстати, если разрешение ранее было отказано, нет смысла запрашивать авторизацию снова, потому что ОС не будет представлять какой-либо пользовательский интерфейс "предоставить доступ" конечному пользователю. Это происходит только в том случае, если пользователь ранее не отказывал в доступе.
Если доступ к контактам действительно необходим для успешной работы приложения, вы можете показать им предупреждение, которое дает им возможность перейти к настройкам прямо из вашего приложения:
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. Would you like to open settings and grant permission to contacts?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { action in
completionHandler(false)
UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!)
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { action in
completionHandler(false)
})
present(alert, animated: true)
}