I have a VoIP application that use CallKit integration.
In my contacts screen I have a UITableView
with all the device contacts and when the user press a contact I populate a CNContactViewController
with:
extension ContactsViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedContact = viewModel.contactAt(section: indexPath.section, index: indexPath.row)
Logd(self.logTag, "\(#function) \(String(describing: selectedContact))")
let contactViewController = CNContactViewController(for: selectedContact!)
contactViewController.title = CNContactFormatter.string(from: selectedContact!,
style: CNContactFormatterStyle.fullName)
contactViewController.contactStore = viewModel.contactStore
contactViewController.allowsActions = false
contactViewController.delegate = self
navigationItem.titleView = nil
navigationController?.pushViewController(contactViewController, animated: true)
tableView.deselectRow(at: indexPath, animated: false)
}
}
This populates the contacts details view without any problem.
I would like to catch the user action on the phone number pressing and perform the VoIP call so I use the following code:
extension ContactsViewController: CNContactViewControllerDelegate {
func contactViewController(_ viewController: CNContactViewController,
shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
if property.key == CNContactPhoneNumbersKey {
let phoneNumberProperty: CNPhoneNumber = property.value as! CNPhoneNumber
let phoneNumber = phoneNumberProperty.stringValue
makeMyVoIPCall(number: phoneNumber!, video: false)
//makeMyVoIPCall(number: "+1234567890", video: false)
return false
}
if property.key == CNContactSocialProfilesKey {
let profile: CNSocialProfile = property.value as! CNSocialProfile
if profile.service == appServiceName {
let phoneNumber = profile.username
makeMyVoIPCall(number: phoneNumber!, video: false)
return false
}
}
Logd(self.logTag, "\(#function) nothing to handle for \(property)")
return true
}
func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
dismiss(animated: true, completion: nil)
}
}
This has as a result when I press the phone item element to initiate 2 calls! One call is performed from my application (VoIP) and the other from the system (SIM/GSM).
What I tried:
CNContactSocialProfilesKey
and at this case the call is performed as expected only once via my application.What is required in order to tell the system that I am handling the action, and the SIM/GSM call should not performed?
I am testing on iOS 12.1.1 (16C50).
Wrapping the makeMyVoIPCall(number: phoneNumber!, video: false)
in a main thread bundle solved the problem.
I cannot really understand why iOS just ignore the false
value otherwise.