【问题标题】:CNContactViewController handle CNContactPhoneNumbersKey along with CallKitCNContactViewController 与 CallKit 一起处理 CNContactPhoneNumbersKey
【发布时间】:2019-05-31 04:55:16
【问题描述】:

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

当我按下电话项目元素以发起 2 个呼叫时,结果就是这样!一个呼叫来自我的应用程序 (VoIP),另一个来自系统 (SIM/GSM)。

我尝试了什么:

  • 添加了用于处理CNContactSocialProfilesKey 的上述代码,在这种情况下,调用仅通过我的应用程序按预期执行一次。
  • 将 makeMyVoIPCall 更改为特定号码,而不是按下的号码(参见上面的注释行)。我再次看到系统调用 clicked 属性的 2 个调用和我的应用程序调用“+1234567890”。
  • 我还验证了在您处理操作时返回值应该为 false 而不是 true。

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

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

【问题讨论】:

    标签: ios swift callkit cncontactviewcontroller


    【解决方案1】:

    makeMyVoIPCall(number: phoneNumber!, video: false) 包装在主线程包中解决了这个问题。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2021-05-22
      • 2012-03-04
      • 1970-01-01
      • 2017-01-11
      • 2018-03-10
      相关资源
      最近更新 更多