Медиа-вложение в iOS 10 Push-уведомлений
Я борюсь с добавлением изображения в свое Push-уведомление в iOS 10.
Я добавил расширение службы уведомлений и использовал следующий код:
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let urlString = request.content.userInfo["image-url"] as? String, let fileUrl = URL(string: urlString) {
URLSession.shared.downloadTask(with: fileUrl) { (location, response, error) in
if let location = location {
let options = [UNNotificationAttachmentOptionsTypeHintKey: kUTTypePNG]
if let attachment = try? UNNotificationAttachment(identifier: "", url: location, options: options) {
self.bestAttemptContent?.attachments = [attachment]
}
}
self.contentHandler!(self.bestAttemptContent!)
}.resume()
}
}
Я получил этот код из первого ответа ниже.
Проблема, с которой я столкнулся, заключается в том, что уведомление получено с небольшой задержкой, которая указывает на то, что загрузка должна происходить, но вложения не отображаются.
Я предполагаю что serviceExtensionTimeWillExpire()
вызывается и просто показывает bestAttempt
Любая помощь с благодарностью.
Я правильно настроил полезную нагрузку APN.
apns: {
aps: {
alert: {
title: "Title",
subtitle: "Subtitle",
body: "Body"
},
"mutable-content": 1
},
"image-url": "https://helloworld.com/image.png"
}
2 ответа
Вы должны извлечь URL-адрес из пользовательской информации уведомления, затем загрузить изображение и указать URL-адрес файла во вложении. Попробуйте что-то вроде:
if let urlString = request.content.userInfo["image-url"] as? String, let fileUrl = URL(string: urlString) {
URLSession.shared.downloadTask(with: fileUrl) { (location, response, error) in
if let location = location {
let options = [UNNotificationAttachmentOptionsTypeHintKey: kUTTypePNG]
if let attachment = try? UNNotificationAttachment(identifier: "", url: location, options: options) {
self.bestAttemptContent.attachments = [attachment]
}
}
self.contentHandler(self.bestAttemptContent)
}.resume()
}
Другое решение (и проверяемое) может заключаться в записи изображения во временном месте:
// NotificationRequestHandler
func getImageURL(from userInfo: [AnyHashable: Any]) throws -> URL {
// parse the image URL and return it, otherwise throws and error
}
func temporaryWriteData(from url: URL) throws -> (String, URL) {
let temporaryDirectoryUrl = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
let temporaryFileName = UUID().uuidString
let temporaryFileUrl = temporaryDirectoryUrl.appendingPathComponent(temporaryFileName)
let data = try Data(contentsOf: url)
try data.write(to: temporaryFileUrl, options: .atomic)
return (temporaryFileName, temporaryFileUrl)
}
и дальше didReceive(_:withContentHandler:)
:
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
defer {
contentHandler(bestAttemptContent ?? request.content)
}
do {
let handler = NotificationRequestHandler()
let imageUrl = try handler.getImageURL(from: request.content.userInfo)
let (imageFileName, imageFileUrl) = try handler.temporaryWriteData(from: imageUrl)
let attachment = try UNNotificationAttachment(identifier: imageFileName, url: imageFileUrl, options: [UNNotificationAttachmentOptionsTypeHintKey: "public.png"])
bestAttemptContent?.attachments = [attachment]
} catch {}
Также кое-что очень полезно для отладки расширений и того, как тестировать расширения.
Мне удалось решить это с помощью следующего кода:
Swift:
if let PusherNotificationData = request.content.userInfo["data"] as? NSDictionary {
if let urlString = PusherNotificationData["image-url"] as? String, let fileUrl = URL(string: urlString) {
URLSession.shared.downloadTask(with: fileUrl) { (location, response, error) in
if let location = location {
let options = [UNNotificationAttachmentOptionsTypeHintKey: kUTTypePNG]
if let attachment = try? UNNotificationAttachment(identifier: "", url: location, options: options) {
self.bestAttemptContent?.attachments = [attachment]
}
}
self.contentHandler!(self.bestAttemptContent!)
}.resume()
}
}
Узел:
apns: {
aps: {
alert: {
title: "title",
subtitle: "subtitle",
body: "body"
},
"mutable-content": 1,
category: "test"
},
data: {
"image-url": "www.helloworld.com/image.png"
}
}
Спасибо за вашу помощь!