I have a table view on which are listed some contacts. When I select one of the contacts, I want to show its details using the CNContactViewController.
Here's the
tableView(_:didDeselectRowAt:)
implementation for that situation:func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedContact = contacts[indexPath.row]
let keys = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), CNContactEmailAddressesKey, CNContactBirthdayKey, CNContactImageDataKey] as [Any]
// We’ll use to make sure that all the keys needed by the contacts view controller exist. This method accepts just one parameter, an array of keys or key descriptors (just like the keys array we used many times to fetch contacts). In the case of the CNContactViewController though we must set the CNContactViewController.descriptorForRequiredKeys() specific value as the only item of the parameter array, as that class method will automatically check for all the existing keys.
if selectedContact.areKeysAvailable([CNContactViewController.descriptorForRequiredKeys()]) {
// In case the keys are available, we’ll present the contacts view controller
let contactViewController = CNContactViewController(for: selectedContact)
contactViewController.contactStore = AppDelegate.getAppDelegate().contactStore
contactViewController.displayedPropertyKeys = keys
navigationController?.pushViewController(contactViewController, animated: true)
} else {
// In the opposite case, we’ll act similarly to what we previously did, and we’ll refetch the contact using the descriptorForRequiredKeys() for specifying the keys that should be fetched.
AppDelegate.getAppDelegate().requestForAccess{ (accessGranted) -> Void in
if accessGranted {
do {
let contactRefetched = try AppDelegate.getAppDelegate().contactStore.unifiedContact(withIdentifier: selectedContact.identifier, keysToFetch: [CNContactViewController.descriptorForRequiredKeys()])
DispatchQueue.main.async {
() -> Void in
let contactViewController = CNContactViewController(for: contactRefetched)
contactViewController.contactStore = AppDelegate.getAppDelegate().contactStore
contactViewController.displayedPropertyKeys = keys
self.navigationController?.pushViewController(contactViewController, animated: true)
}
} catch {
print("Unabled to refetch the selected contact", separator: " ", terminator: "\n")
}
}
}
}
}
The problem is that the resulting controller is blank and the following message is logged:
[CNUI ERROR] error calling service - Couldn’t communicate with a helper application.
I also noticed that if instead of keys, on lines 11 and 25 I use:
[CNContactGivenNameKey, CNContactEmailAddressesKey, CNContactBirthdayKey, CNContactImageDataKey]
I got the desired resoult, I mean: a controller filled with the desired data. The question is: what's wrong with this code that results on a blank controller?