首页 > 解决方案 > 通过推送通知发送图像在 iOS 中不起作用

问题描述

根据文档,我添加了 NotificationExtension。这是代码

import UserNotifications
import Firebase
import FirebaseMessaging

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            // Modify the notification content here...
            bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"

            //contentHandler(bestAttemptContent)
        }

        Messaging.serviceExtension().populateNotificationContent(self.bestAttemptContent!, withContentHandler: contentHandler)
    }

    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

firebase 控制台显示图像

[![在此处输入图像描述][1]][1]

然而,在调试中,didReceive 从来没有打电话,我收到的通知也没有图像,即使我已经在我的 iPhone 设置中将通知设置为持久。

需要做什么来解决这个问题?如何查看 NotificationService 是否正确附加到我的应用程序

[

AnyHashable("google.c.a.ts"): 1575541521, AnyHashable("aps"): {
    alert =     {
        body = "Test for imge";
        title = Test;
    };
    "mutable-content" = 1;
    sound = default;
}, AnyHashable("google.c.a.e"): 1, AnyHashable("google.c.a.c_l"): Data, AnyHashable("fcm_options"): {
    image = "https://thevowapp.com/iphoneapp/peri/media/portstar.png";
}, AnyHashable("gcm.notification.sound2"): default, AnyHashable("google.c.a.udt"): 0, AnyHashable("gcm.n.e"): 1, AnyHashable("gcm.message_id"): 1575541521949602, AnyHashable("google.c.a.c_id"): 5702933232519496714]

在此处输入图像描述

也向扩展添加了通知,但我没有看到任何背景模式 atm,但它们不是必需的,因为代码还没有。调试器仍然不会滚动。

标签: swiftiphonefirebasefirebase-cloud-messaging

解决方案


首先,您的通知负载应该mutable-content包含aps.

这个参数很重要。

如果不存在于 中aps,那么您的 NotificationService 将不会被调用,并且您将不会在通知的右侧获得图像。

这里的文档:

可变内容:Int

通知服务应用扩展标志。如果值为 1,则系统在发送前将通知传递给您的通知服务应用扩展。使用您的扩展程序来修改通知的内容。

其次,您需要在您的 notificationService 中下载图像并将其附加到通知中。

您可以使用下面的示例作为起点。这取决于您如何在有效负载中发送图像链接。如果您将发布您的实际有效负载,那么我可以编辑我的帖子。

import UserNotifications
import Foundation
import SwiftyJSON

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            let apsData = request.content.userInfo["aps"] as! [String : Any]
            let alertData = apsData["alert"] as! [String : Any]
            let imageData = request.content.userInfo["fcm_options"] as! [String : Any]
            bestAttemptContent.title = (alertData["title"] as? String) ?? ""
            bestAttemptContent.body = (alertData["body"] as? String) ?? ""

            guard let urlImageString = imageData["image"] as? String else {
                contentHandler(bestAttemptContent)
                return
            }
            if let newsImageUrl = URL(string: urlImageString) {

                guard let imageData = try? Data(contentsOf: newsImageUrl) else {
                    contentHandler(bestAttemptContent)
                    return
                }
                guard let attachment = UNNotificationAttachment.saveImageToDisk(fileIdentifier: "newsImage.jpg", data: imageData, options: nil) else {
                    contentHandler(bestAttemptContent)
                    return
                }
                bestAttemptContent.attachments = [ attachment ]
            }
            Messaging.serviceExtension().populateNotificationContent(self.bestAttemptContent!, withContentHandler: contentHandler)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

//MARK: Extension for Notification Attachment
extension UNNotificationAttachment {

    static func saveImageToDisk(fileIdentifier: String, data: Data, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
        let fileManager = FileManager.default
        let folderName = ProcessInfo.processInfo.globallyUniqueString
        let folderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(folderName, isDirectory: true)

        do {
            try fileManager.createDirectory(at: folderURL!, withIntermediateDirectories: true, attributes: nil)
            let fileURL = folderURL?.appendingPathComponent(fileIdentifier)
            try data.write(to: fileURL!, options: [])
            let attachment = try UNNotificationAttachment(identifier: fileIdentifier, url: fileURL!, options: options)
            return attachment
        } catch let error {
            print("error \(error)")
        }

        return nil
    }
}

推荐阅读