Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 通过推送通知发送图像在iOS中不起作用_Swift_Iphone_Firebase_Firebase Cloud Messaging - Fatal编程技术网

Swift 通过推送通知发送图像在iOS中不起作用

Swift 通过推送通知发送图像在iOS中不起作用,swift,iphone,firebase,firebase-cloud-messaging,Swift,Iphone,Firebase,Firebase Cloud Messaging,根据文档,我添加了NotificationExtension。这是密码 import UserNotifications import Firebase import FirebaseMessaging class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptConte

根据文档,我添加了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]

然而,在debug中,didReceive从不调用,我收到的通知也没有图像,即使我在iPhone设置中将通知设置为持久

需要采取什么措施来解决此问题?如何查看NotificationService是否正确连接到我的应用程序

[


也向扩展添加了通知,但我看不到任何后台模式atm,尽管它们不是必需的,因为代码还没有出现。调试器仍然无法运行。

首先,通知负载应该包括
aps
中的参数
可变内容

此参数很重要。

如果在
aps
中不存在,则您的通知服务将不会被调用,并且您将无法获得通知右侧的图像

从文件:

可变内容:Int

notification service应用程序扩展标志。如果该值为1,则系统会在传递之前将通知传递给notification service应用程序扩展。使用您的扩展来修改通知的内容

其次,您需要在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
    }
}

首先,您的通知负载应该包括
aps
中的参数
可变内容

此参数很重要。

如果在
aps
中不存在,则您的通知服务将不会被调用,并且您将无法获得通知右侧的图像

从文件:

可变内容:Int

notification service应用程序扩展标志。如果该值为1,则系统会在传递之前将通知传递给notification service应用程序扩展。使用您的扩展来修改通知的内容

其次,您需要在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
    }
}

然后,您将缺少实际下载图像并将其作为附件添加到通知中的部分。我在该位置放置了一个调试器,而代码从未进入该服务。Firebase还允许您添加Messaging.serviceExtension().populateNotificationContent(self.bestAttemptContent!,withContentHandler:contentHandler)这将自动处理fcm,遗憾的是它不起作用。我更新了我的代码以使用您的AP。另外,您是否在XCode中运行扩展?否则您将永远无法调试它。选择扩展作为目标,并在真实设备上点击Build。一旦我运行扩展,它将打开应用程序,然后在到达主屏幕后自动关闭它,就像崩溃一样,没有错误。当您缺少实际下载图像并将其作为附件添加到通知中的部分时。我在该位置放置了调试器,代码从未进入该服务。Firebase还允许您添加消息传递。serviceExtension().populateNotificationContent(self.bestAttemptContent!,withContentHandler:contentHandler)这将自动处理fcm,遗憾的是它不起作用。我更新了我的代码以使用您的AP。另外,您是否在XCode中运行扩展?否则您将永远无法调试它。选择扩展作为目标,并在真实设备上点击Build。一旦我运行扩展,它将打开应用程序,然后在到达主屏幕后自动关闭它,就像撞车一样,没有错误,什么都没有