5

我一步一步地获得丰富的推送通知。他们来了 :

  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;
} 

我确实尝试过以下帖子,但这没有帮助:

iOS10 UNNotificationServiceExtension not called
NotificationServiceExtension not called
UNNotificationServiceExtension 在 iPhone 5 (iOS 10) 上不起作用

4

1 回答 1

16

好消息!您的服务扩展确实被调用了 - 您通知上的图像就是证明。这里可能发生的情况是,您无法使用您习惯的应用程序工作流程来调试扩展。

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

调试通知服务扩展

  1. 从 Xcode 或设备启动应用程序
  2. 在 Xcode 中,从Debug菜单 中选择Attach To Process 或 PID By Name...Xcode Debug 菜单,Attach To Process 或 PID By Name...
  3. 输入您的通知扩展名 Xcode 调试菜单,输入进程名称
  4. 触发通知(通过发送推送等)。

发送通知后,服务扩展应该在调试器中启动。服务扩展仅与远程(推送)通知相关,因此您需要使用设备对其进行故障排除。

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

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

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

为什么视频可能无法播放

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

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

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

如果您想为您的视频实现“自动播放” - 从您的问题中不清楚您所描述的内容 - 您需要在内容扩展中实现自己的播放器功能。

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

于 2018-08-10T04:49:05.227 回答