通过推送通知发送图像在 iOS 中不起作用
Sending image Via Push notification not working in 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,虽然它们不是必需的,因为代码还不存在。调试器仍然不会滚动。
首先,您的通知负载应在 aps
.
中包含参数 mutable-content
THIS PARAMETER IS IMPORTANT.
If not present inside the aps
, then your NotificationService won't get called and you won't get the image on the right side of the notification.
来自文档 here:
mutable-content : Int
The notification service app extension flag. If the value is 1, the system passes the notification to your notification service app extension before delivery. Use your extension to modify the notification’s content.
其次,您需要在 notificationService 中下载图片并将其附加到通知中。
您可以使用下面的示例作为起点。这取决于您如何在负载中发送图像 link。如果您 post 您的实际负载,那么我可以编辑我的 post.
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
}
}
根据文档,我添加了 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,虽然它们不是必需的,因为代码还不存在。调试器仍然不会滚动。
首先,您的通知负载应在 aps
.
mutable-content
THIS PARAMETER IS IMPORTANT.
If not present inside the
aps
, then your NotificationService won't get called and you won't get the image on the right side of the notification.
来自文档 here:
mutable-content : Int
The notification service app extension flag. If the value is 1, the system passes the notification to your notification service app extension before delivery. Use your extension to modify the notification’s content.
其次,您需要在 notificationService 中下载图片并将其附加到通知中。
您可以使用下面的示例作为起点。这取决于您如何在负载中发送图像 link。如果您 post 您的实际负载,那么我可以编辑我的 post.
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
}
}