iOS 推送通知中的图片
Images in iOS push notification
我正尝试在推送通知中发送 images
我已经在应用程序委托中进行了通知注册,并且 apns 设备令牌正在正确生成。
另外我在服务分机中编码如下:
import UserNotifications
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)
// Get the custom data from the notification payload
if let notificationData = request.content.userInfo["data"] as? [String: String] {
// Grab the attachment
if let urlString = notificationData["attachment-url"], let fileUrl = URL(string: urlString) {
// 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: "", url: tmpUrl) {
self.bestAttemptContent?.attachments = [attachment]
}
}
// Serve the notification content
self.contentHandler!(self.bestAttemptContent!)
}.resume()
}
}
}
}
。
而json中的payload如下
{
"aps":
{"sound":"default","alert":
{"title":"iOS","body":"Hello Dude...."},
"mutable-content": 1},
"CustomData":
{"mType":"alert","m":"Hello Dude...."},
"Attachement-url":"https://pusher.com/static_logos/320x320.png"
}
我收到了标题和消息,但是图片没有收到。
请指导如何在推送通知中获取图像
对于 Swift,如果你愿意,可以尝试使用 this framework
同时在你的 aps 中添加 "content-available":1
或者您可以尝试这样下载,
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as?UNMutableNotificationContent)
bestAttemptContent?.title = request.content.title
bestAttemptContent?.body = request.content.body
guard let content = (request.content.mutableCopy() as? UNMutableNotificationContent) else {
return failEarly()
}
guard let payload = content.userInfo["CustomData"] as? [String: Any] else {
return failEarly()
}
guard let attachmentURL = payload["Attachement-url"] as? String else {
return failEarly()
}
let identifierName = getIdentifierName(fileURL: attachmentURL)
let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
guard let imageData = NSData(contentsOf:NSURL(string: attachmentURL)! as URL) else { return failEarly() }
guard let attachment = UNNotificationAttachment.create(imageFileIdentifier: identifierName, data: imageData, options: nil, tmpSubFolderName: tmpSubFolderName) else { return failEarly() }
content.attachments = [attachment]
contentHandler(content.copy() as! UNNotificationContent)
}
}
func getIdentifierName(fileURL : String) -> String {
var identifierName : String = "image.jpg"
if !fileURL.isEmpty() {
identifierName = "file.\((fileURL as NSString).lastPathComponent)"
}
return identifierName
}
func failEarly() {
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
extension UNNotificationAttachment {
static func create(imageFileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?, tmpSubFolderName : String) -> UNNotificationAttachment? {
let fileManager = FileManager.default
let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
let fileURLPath = NSURL(fileURLWithPath: NSTemporaryDirectory())
let tmpSubFolderURL = fileURLPath.appendingPathComponent(tmpSubFolderName, isDirectory: true)
do {
try fileManager.createDirectory(at: tmpSubFolderURL!, withIntermediateDirectories: true, attributes: nil)
let fileURL = tmpSubFolderURL?.appendingPathComponent(imageFileIdentifier)
try data.write(to: fileURL!, options: [])
let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, url: fileURL!, options: options)
return imageAttachment
} catch let error {
print("error \(error)")
}
return nil
}
}
这一行:
if let urlString = notificationData["attachment-url"], let fileUrl = URL(string: urlString) {
正在 userInfo 字典中寻找 attachment-url
值作为 data
对象的子对象。
它正在寻找这个:
{
"aps" : {
...
},
"data" : {
"attachment-url" : "some url"
}
}
但是你问题中的payload是这样的:
{
"aps":{
"sound":"default",
"alert": {
"title":"iOS",
"body":"Hello Dude...."
},
"mutable-content": 1
},
"CustomData": {
"mType":"alert",
"m":"Hello Dude...."
},
"Attachement-url":"https://pusher.com/static_logos/320x320.png"
}
"data" 部分不存在,attachment-url
键不存在。
更改您的 Swift 代码以匹配负载中的内容,您应该能够获取图像 URL 并下载它。
如果您收到的通知 没有 附件 URL 密钥或附件 URL 不正确形成URL。在这些情况下,您的 if let
将不会被输入并且 contentHandler
将不会被调用!这不仅会导致服务扩展锁定,还会阻止任何没有附件 URL 的通知被传递!添加一个调用 contentHandler
的 else
来解决这个问题。
下载完成后还有另一个问题。 iOS 需要知道您在附件中放入的数据类型。附件选项字典允许您包含有关附件的类型信息。获取下载文件的 MIME 类型并从中创建统一类型标识符。然后可以在选项字典中使用统一类型标识符字符串。
我在 iOS Notifications book 中深入介绍了所有这些内容。现在可用的示例章节涉及将图像添加到通知。
我正尝试在推送通知中发送 images
我已经在应用程序委托中进行了通知注册,并且 apns 设备令牌正在正确生成。
另外我在服务分机中编码如下:
import UserNotifications
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)
// Get the custom data from the notification payload
if let notificationData = request.content.userInfo["data"] as? [String: String] {
// Grab the attachment
if let urlString = notificationData["attachment-url"], let fileUrl = URL(string: urlString) {
// 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: "", url: tmpUrl) {
self.bestAttemptContent?.attachments = [attachment]
}
}
// Serve the notification content
self.contentHandler!(self.bestAttemptContent!)
}.resume()
}
}
}
}
。 而json中的payload如下
{
"aps":
{"sound":"default","alert":
{"title":"iOS","body":"Hello Dude...."},
"mutable-content": 1},
"CustomData":
{"mType":"alert","m":"Hello Dude...."},
"Attachement-url":"https://pusher.com/static_logos/320x320.png"
}
我收到了标题和消息,但是图片没有收到。 请指导如何在推送通知中获取图像
对于 Swift,如果你愿意,可以尝试使用 this framework
同时在你的 aps 中添加 "content-available":1
或者您可以尝试这样下载,
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as?UNMutableNotificationContent)
bestAttemptContent?.title = request.content.title
bestAttemptContent?.body = request.content.body
guard let content = (request.content.mutableCopy() as? UNMutableNotificationContent) else {
return failEarly()
}
guard let payload = content.userInfo["CustomData"] as? [String: Any] else {
return failEarly()
}
guard let attachmentURL = payload["Attachement-url"] as? String else {
return failEarly()
}
let identifierName = getIdentifierName(fileURL: attachmentURL)
let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
guard let imageData = NSData(contentsOf:NSURL(string: attachmentURL)! as URL) else { return failEarly() }
guard let attachment = UNNotificationAttachment.create(imageFileIdentifier: identifierName, data: imageData, options: nil, tmpSubFolderName: tmpSubFolderName) else { return failEarly() }
content.attachments = [attachment]
contentHandler(content.copy() as! UNNotificationContent)
}
}
func getIdentifierName(fileURL : String) -> String {
var identifierName : String = "image.jpg"
if !fileURL.isEmpty() {
identifierName = "file.\((fileURL as NSString).lastPathComponent)"
}
return identifierName
}
func failEarly() {
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
extension UNNotificationAttachment {
static func create(imageFileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?, tmpSubFolderName : String) -> UNNotificationAttachment? {
let fileManager = FileManager.default
let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
let fileURLPath = NSURL(fileURLWithPath: NSTemporaryDirectory())
let tmpSubFolderURL = fileURLPath.appendingPathComponent(tmpSubFolderName, isDirectory: true)
do {
try fileManager.createDirectory(at: tmpSubFolderURL!, withIntermediateDirectories: true, attributes: nil)
let fileURL = tmpSubFolderURL?.appendingPathComponent(imageFileIdentifier)
try data.write(to: fileURL!, options: [])
let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, url: fileURL!, options: options)
return imageAttachment
} catch let error {
print("error \(error)")
}
return nil
}
}
这一行:
if let urlString = notificationData["attachment-url"], let fileUrl = URL(string: urlString) {
正在 userInfo 字典中寻找 attachment-url
值作为 data
对象的子对象。
它正在寻找这个:
{
"aps" : {
...
},
"data" : {
"attachment-url" : "some url"
}
}
但是你问题中的payload是这样的:
{
"aps":{
"sound":"default",
"alert": {
"title":"iOS",
"body":"Hello Dude...."
},
"mutable-content": 1
},
"CustomData": {
"mType":"alert",
"m":"Hello Dude...."
},
"Attachement-url":"https://pusher.com/static_logos/320x320.png"
}
"data" 部分不存在,attachment-url
键不存在。
更改您的 Swift 代码以匹配负载中的内容,您应该能够获取图像 URL 并下载它。
如果您收到的通知 没有 附件 URL 密钥或附件 URL 不正确形成URL。在这些情况下,您的 if let
将不会被输入并且 contentHandler
将不会被调用!这不仅会导致服务扩展锁定,还会阻止任何没有附件 URL 的通知被传递!添加一个调用 contentHandler
的 else
来解决这个问题。
下载完成后还有另一个问题。 iOS 需要知道您在附件中放入的数据类型。附件选项字典允许您包含有关附件的类型信息。获取下载文件的 MIME 类型并从中创建统一类型标识符。然后可以在选项字典中使用统一类型标识符字符串。
我在 iOS Notifications book 中深入介绍了所有这些内容。现在可用的示例章节涉及将图像添加到通知。