簡體   English   中英

請求訪問 Swift 3 中的聯系人

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM