Приложение зависает при запросе доступа к адресной книге

func getContacts() {
    let store = CNContactStore()

    if CNContactStore.authorizationStatus(for: .contacts) == .notDetermined {
        store.requestAccess(for: .contacts, completionHandler: { (authorized: Bool, error: NSError?) -> Void in
            if authorized {
                self.retrieveContactsWithStore(store: store)
            }
        } as! (Bool, Error?) -> Void)
    } else if CNContactStore.authorizationStatus(for: .contacts) == .authorized {
        self.retrieveContactsWithStore(store: store)
    }
}

func retrieveContactsWithStore(store: CNContactStore) {
    do {
        let groups = try store.groups(matching: nil)
        let predicate = CNContact.predicateForContactsInGroup(withIdentifier: groups[0].identifier)
        //let predicate = CNContact.predicateForContactsMatchingName("John")
        let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), CNContactEmailAddressesKey] as [Any]

        let contacts = try store.unifiedContacts(matching: predicate, keysToFetch: keysToFetch as! [CNKeyDescriptor])
        self.objects = contacts
        DispatchQueue.main.async(execute: { () -> Void in
            self.myTableView.reloadData()
        })
    } catch {
        print(error)
    }
}

Я пытался получить контакты из адресной книги, но всякий раз, когда я перехожу к представлению, вызывающему getContacts(), приложение зависает. Это больше не будет продолжаться, но и не рухнуло. Интересно, что здесь пошло не так?

1 ответ

Решение

Ваш код для звонка requestAccess не правильно Синтаксис для обработчика завершения недопустим. Ты нуждаешься в этом:

func getContacts() {
    let store = CNContactStore()

    let status = CNContactStore.authorizationStatus(for: .contacts)
    if status == .notDetermined {
        store.requestAccess(for: .contacts, completionHandler: { (authorized: Bool, error: Error?) in
            if authorized {
                self.retrieveContactsWithStore(store: store)
            }
        })
    } else if status == .authorized {
        self.retrieveContactsWithStore(store: store)
    }
}

Также обратите внимание на изменение, чтобы использовать status переменная. Это чище и легче читать, чем звонить authorizationStatus вновь и вновь. Вызовите его один раз, а затем проверяйте значение снова и снова по мере необходимости.

Другие вопросы по тегам