授予联系人权限后,Tableview 不会重新加载

Tableview won't reload after contacts permission granted

我正在使用 Swift 4.2 和 Xcode 10.2.1。

在联系人权限请求出现并获得批准后,我需要帮助重新加载表格视图。目前,对话框显示在首次使用时请求权限,但在首次使用期间授予权限后,tableview 将不会重新加载。如果我关闭应用程序并重新打开,联系人会按预期显示(换句话说,当请求权限对话框不显示时它显示正常)。这是我的代码:

ContactsViewControllerviewDidLoad中:

    // Load the contacts from the phone
    ContactService.fetchContacts(completion: { (contacts) in
        if contacts != nil {
            self.deviceContacts = contacts!
            self.tableView.reloadData()
            }
    })

ContactService中:

static func fetchContacts(completion: @escaping (_ contacts: [Contact]?) -> Void) {

    var deviceContacts:[Contact] = [Contact]()

    // Set up default storage for the contacts
    let store = CNContactStore()

    // Request access to the contacts if not already given.
    store.requestAccess(for: .contacts) { (granted, error) in

        if let error = error {

            print("Failed to request access:", error)
            completion (nil)
        }

        if granted {
            print("Access granted.")

            // Information to retrieve
            let keys = [CNContactIdentifierKey, CNContactGivenNameKey, CNContactFamilyNameKey, CNContactNicknameKey, CNContactNameSuffixKey, CNContactOrganizationNameKey, CNContactPhoneNumbersKey, CNContactImageDataAvailableKey, CNContactImageDataKey]

            let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])

            // Sort by last name
            request.sortOrder = CNContactSortOrder.familyName

            do {

                try store.enumerateContacts(with: request
                    , usingBlock: { (contact, stopPointerifYouWantToStopEnumerating) in

                        // Got the contacts from the device, now format as a Contact and put them into our array
                        let formattedContact = Contact(contactDetails: contact, favoriteNumbers: [], opened: false)
                        deviceContacts.append(formattedContact)
                })

            } catch let error {
                print("Failed to enumerate contacts:", error)
            }
        } else {
            print ("Access denied.")
            completion (nil)
        }
    }
        completion(deviceContacts)
}

我尝试在 fetchContacts 的完成中将 dispatchGroup.enter().leave() 放入 if granted.notify 中,但它没有用。

您需要更改 completion

的位置
try store.enumerateContacts(with: request
    , usingBlock: { (contact, stopPointerifYouWantToStopEnumerating) in

        // Got the contacts from the device, now format as a Contact and put them into our array
        let formattedContact = Contact(contactDetails: contact, favoriteNumbers: [], opened: false)
        deviceContacts.append(formattedContact)
})  
completion(deviceContacts)

目前 store.requestAccess(for: .contacts) { (granted, error) in 不应该检索联系人,而且您在这里不需要调度组,因为它是 1 个异步任务,数量不多


requestAccess 的结果出现在后台线程中,因此请考虑

DispatchQueue.main.async { 
  self.tableView.reloadData()
}