UNNotificationServiceExtension didReceive 未调用

UNNotificationServiceExtension's didRecieve not called

为了获得丰富的推送通知,我一步步前进。他们在这里:

  1. 使用 plist 创建了通知服务扩展:

NotificationService didRecieve :

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {

        func failEarly() {
            contentHandler(request.content)
        }

        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        // Get the custom data from the notification payload
        if let data = request.content.userInfo as? [String: AnyObject] {
            // Grab the attachment
            //            let notificationData = data["data"] as? [String: String]
            if let urlString = data["attachment-url"], let fileUrl = URL(string: urlString as! String) {
                // Download the attachment
                URLSession.shared.downloadTask(with: fileUrl) { (location, response, error) in
                    if let location = location {
                        // Move temporary file to remove .tmp extension
                        let tmpDirectory = NSTemporaryDirectory()
                        let tmpFile = "file://".appending(tmpDirectory).appending(fileUrl.lastPathComponent)
                        let tmpUrl = URL(string: tmpFile)!
                        try! FileManager.default.moveItem(at: location, to: tmpUrl)

                        // Add the attachment to the notification content
                        if let attachment = try? UNNotificationAttachment(identifier: "video", url: tmpUrl, options:nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }else if let attachment = try? UNNotificationAttachment(identifier: "image", url: tmpUrl, options:nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }else if let attachment = try? UNNotificationAttachment(identifier: "audio", url: tmpUrl, options:nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }else if let attachment = try? UNNotificationAttachment(identifier: "image.gif", url: tmpUrl, options: nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }
                    }
                    // Serve the notification content
                    self.contentHandler!(self.bestAttemptContent!)
                    }.resume()
            }
        }
    }
  1. 已为扩展配置 AppId 和配置文件。

丰富的通知正确到达:

但这是我面临的问题:

  1. didRecieve 未被调用。为此,我将 serviceExtension 过程附加到应用程序目标和 运行 应用程序。
    注意:通知到达后立即调用扩展,但未调用 didRecieve:

  1. 打开推送通知(有视频附件)时,没有任何反应。 理想情况下应该播放。
  2. 如果我必须打开视频并播放它,我是否必须明确做某事或扩展程序会处理?

有效负载

aps =     {
        alert = "This is what your message will look like! Type in your message in the text area and get a preview right here";
        badge = 1;
        "mutable-content" = 1;
        sound = default;
    };
    "attachment-url" = "https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4";
    deeplinkurl = "";
    "message_id" = 1609;
} 

我确实尝试浏览了以下帖子,但没有帮助:


NotificationServiceExtension not called

好消息!您的服务扩展确实被调用了——您通知中的图像就是证据。此处可能发生的情况是您无法使用您在应用程序中习惯的工作流程来调试扩展。

调试通知扩展不像调试应用程序。扩展是应用程序外部 iOS 进程的插件。仅仅设置断点并不是调试它们的可靠方法。相反:

调试通知服务扩展

  1. 从 Xcode 或设备
  2. 启动应用程序
  3. 在 Xcode、select 按名称附加到进程或 PID... 来自 Debug菜单
  4. 输入您的通知扩展名
  5. 触发通知(通过发送推送等)。

发送通知后,服务扩展应该在调试器中启动。服务扩展仅与远程(推送)通知相关,因此您需要一个设备来解决它们。

调试通知内容扩展 至少有两种方法。上面显示的服务扩展步骤也适用于内容扩展。第二种方法比较熟悉,但不太可靠。

  1. Select Xcode 中的扩展方案使用工具栏
  2. 在“产品”菜单中,select 编辑方案...
  3. 可执行文件设置为父应用程序。
  4. 在内容扩展中设置断点。
  5. 现在构建并 运行 您的扩展。它将启动父应用程序。
  6. 触发将导致加载内容扩展的通知。

值得注意的是,使用日志记录框架添加日志记录对于调试和故障排除也非常有用。

为什么视频可能无法播放

iOS 限制可以在通知中显示的内容的大小。 UNNotificationAttachment 的文档中对此进行了描述。对于视频,它通常是 50Mb。确保您的视频尽可能小(以字节为单位),当然还要提供适合其播放设备大小的视频。不要尝试在 400 点宽的通知中播放 1080p 视频!

在实践中,使用 HLS 而不是下载视频并在内容扩展中呈现它几乎总是更好。

您的代码中可能有问题的另一件事是您分配给附件的标识符。标识符应 唯一 。通常这将是一个反向域表示法字符串,例如您的包 ID 后跟一个 UUID 字符串。您还可以使用内容的原始 URL 后跟 UUID 字符串。如果您提供空字符串 iOS 将为您创建一个唯一标识符。 具有非唯一标识符(用于通知、附件等)的用户通知框架往往会导致难以追踪框架内的问题。例如,这可能会导致连接的 watchOS 设备崩溃。

如果您想为您的视频实现 "auto play" - 从您的问题中不清楚您所描述的是什么 - 您将需要在内容扩展中实现您自己的播放器功能。

如果您要这样做,HLS 是在通知中显示视频的首选方式。它通常使用更少的 RAM,提供更好的用户体验并且往往更稳定。