CNContactViewController 处理 CNContactPhoneNumbersKey 和 CallKit
CNContactViewController handle CNContactPhoneNumbersKey along with CallKit
我有一个使用 CallKit 集成的 VoIP 应用程序。
在我的联系人屏幕中,我有一个包含所有设备联系人的 UITableView
,当用户按下联系人时,我会在 CNContactViewController
中填充:
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)
}
}
这会毫无问题地填充联系人详细信息视图。
我想捕捉用户按下 phone 号码的操作并执行 VoIP 呼叫,因此我使用以下代码:
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)
}
}
这是当我按下 phone 项目元素发起 2 个调用时的结果!一个呼叫是从我的应用程序 (VoIP) 执行的,另一个是从系统执行的 (SIM/GSM)。
我尝试了什么:
- 添加了上述处理
CNContactSocialProfilesKey
的代码,在这种情况下,调用仅通过我的应用程序按预期执行一次。
- 将 makeMyVoIPCall 更改为特定号码而不是按下(参见上面的注释行)。我再次看到系统调用了 2 个调用 属性,我的应用程序调用了“+1234567890”。
- 我还验证了 return 值应该是 false 而不是 true,当你处理这个动作时。
需要什么才能告诉系统我正在处理该操作,并且不应执行 SIM/GSM 调用?
我正在 iOS 12.1.1 (16C50) 上测试。
将 makeMyVoIPCall(number: phoneNumber!, video: false)
包装在主线程包中解决了问题。
我真的不明白为什么 iOS 忽略 false
值。
我有一个使用 CallKit 集成的 VoIP 应用程序。
在我的联系人屏幕中,我有一个包含所有设备联系人的 UITableView
,当用户按下联系人时,我会在 CNContactViewController
中填充:
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)
}
}
这会毫无问题地填充联系人详细信息视图。
我想捕捉用户按下 phone 号码的操作并执行 VoIP 呼叫,因此我使用以下代码:
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)
}
}
这是当我按下 phone 项目元素发起 2 个调用时的结果!一个呼叫是从我的应用程序 (VoIP) 执行的,另一个是从系统执行的 (SIM/GSM)。
我尝试了什么:
- 添加了上述处理
CNContactSocialProfilesKey
的代码,在这种情况下,调用仅通过我的应用程序按预期执行一次。 - 将 makeMyVoIPCall 更改为特定号码而不是按下(参见上面的注释行)。我再次看到系统调用了 2 个调用 属性,我的应用程序调用了“+1234567890”。
- 我还验证了 return 值应该是 false 而不是 true,当你处理这个动作时。
需要什么才能告诉系统我正在处理该操作,并且不应执行 SIM/GSM 调用?
我正在 iOS 12.1.1 (16C50) 上测试。
将 makeMyVoIPCall(number: phoneNumber!, video: false)
包装在主线程包中解决了问题。
我真的不明白为什么 iOS 忽略 false
值。