CNContactViewController句柄CNContactPhoneNumbersKey和CallKit

时间:2019-01-04 15:37:36

标签: ios swift callkit cncontactviewcontroller

我有一个使用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)
    }
}

这将填充联系人详细信息视图,而不会出现任何问题。

我想在按电话号码时捕获用户操作并执行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次调用,系统调用了clicked属性,而我的应用程序称为“ +1234567890”。
  • 我还验证了处理操作时返回值应该为false而不是true。

要告诉系统我正在处理操作,并且不应该执行SIM / GSM呼叫,需要什么?

我正在iOS 12.1.1(16C50)上进行测试。

1 个答案:

答案 0 :(得分:0)

makeMyVoIPCall(number: phoneNumber!, video: false)包裹在主线程束中解决了该问题。

我真的不明白为什么iOS会忽略false值。