【问题标题】:Cannot receive VoIP messages in background/suspended state in iOS 13 Devices在 iOS 13 设备中无法在后台/挂起状态下接收 VoIP 消息
【发布时间】:2019-12-03 05:02:32
【问题描述】:

我正在开发一个聊天应用程序。为了增强消息传递体验,我使用 VoIP 推送将消息传递到处于后台/已终止状态的应用程序。我猜这就是whatsapp的做法。它在 13.0 之前的 iOS 版本的设备上运行良好。但是,在 iOS 13 设备上,推送仅处于前台状态。在后台状态下,我无法在didReceiveIncomingPushWith 委托方法中获得回调。我浏览了一些在线博客,其中写到苹果现在将其限制为仅用于通话目的。人们提出的另一件事是,如果应用程序分布在 XCode 10 上,即使用 iOS 12 SDK 编译,那么它也应该可以工作。但是,无论我使用什么 XCode,它都不适用于我的情况。我的目标是即使应用程序像whatsapp一样在后台被杀死/在后台也能将消息传递给用户。对此的任何想法/指导都将受到高度赞赏。谢谢

【问题讨论】:

    标签: apple-push-notifications chat voip ios13


    【解决方案1】:

    我遇到了完全相同的问题;我的问题是在 iOS 13 上有一个新的 pushkit 委托方法:

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void
    

    它不同于原型末尾的完成处理程序(现已弃用)。 文档声明您必须调用完成处理程序(即使是无效的)来告诉 CallKit 该调用已被处理。 如果不遵守,将禁止您的应用在后台或强制退出状态下接收 pushkit 通知。当应用程序在前台时它仍然有效。

    我解决了将以下代码添加到我的应用程序的问题:

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
            NSLog("Got new callback incoming notification")
            self.pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type)
            DispatchQueue.main.async {
              completion()
            }
        }
    

    附:要清除 banned 状态(在我的测试中 2-3 次合规失败后触发),您需要从设备中完全删除应用程序并重新开始。

    【讨论】:

    • 嗨@alienpenguin,我按照你说的做了。现在我可以在后台收到通知,但应用程序崩溃了。并且在 3-4 次之后,push 也停止了。还请告诉我“self.pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type)”这个你正在调用的方法。当我尝试调用它时,它会出错。
    • 在回调中,您必须调用 reportNewIncomingCall 并告诉 callkit 有新的呼叫到达。如果你不这样做,应用程序将会崩溃,并且在几次之后它不会再次收到推送通知,直到你重新安装它
    • @Alienpenguin 谢谢你的信息
    【解决方案2】:

    您需要在 iOS 13 中使用 CallKit。

    对于使用 iOS 13 SDK 或更高版本构建的应用,PushKit 要求您在处理 VoIP 呼叫时使用 CallKit。 CallKit 确保在用户设备上提供通话相关服务的应用在用户设备上无缝协作,并尊重“请勿打扰”等功能

    还有

    如果您的应用无法支持 CallKit,则无法使用 PushKit 处理推送通知。相反,请使用 UserNotifications 框架配置您的应用的推送通知支持。

    Apple's documentation

    【讨论】:

    • 感谢您的回复。但是我的问题有点不同。我正在使用 Callkit 和 PushKit 进行音频/视频通话,它工作正常。但我也使用 Pushkit 在后台/已终止状态下传递即时消息。这在 iOS 13 上停止工作。我只需要知道我是否仍然可以利用 Pushkit 功能或使用其他东西在后台传递消息。
    • 是的,除了 UserNotification,我不知道任何其他方式。但我认为这将是面向用户的,不会完全是背景。
    【解决方案3】:

    是的,我们可以为它使用通知内容扩展。 我们可以告诉我们的消息服务器消息已被传递。 如果需要,我们还可以在主应用程序和内容扩展之间共享本地数据库。 如果我们在 APNS 中传递实际消息,我们可以从服务器获取实际消息。 通知内容扩展将提供大约 30 秒的窗口来同步数据。

    【讨论】:

    • 如果应用被杀了怎么办?它还在为你工作吗?
    • 是的,当主应用程序处于后台或终止状态时,扩展程序会被调用事件。我们可以告诉服务器消息已经从扩展传递过来了。
    【解决方案4】:

    一般而言,VoIP 实施包含以下步骤:

    1. 添加 VoIP 功能
    2. 注册 voip-Pushes:
    private func registerForVoIPPushes() {
       voipRegistry = PKPushRegistry(queue: nil)
       voipRegistry?.delegate = self
       voipRegistry?.desiredPushTypes = [.voIP]
    }
    
    1. UNUserNotificationCenterDelegate 的实现
    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void)
    
    
    1. Offcourse服务器端部分实现

    2. !最常见的问题: 一旦应用程序收到 VoIP 通知并且没有将其报告给 CXProvider 对象,它就不会再收到通知,直到您重新安装它。因此,请务必报告您获得的每个 VoIP。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 1970-01-01
      • 2010-12-29
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多