需求:在推送的时候带上一张图.
服务端:
发送指定格式的推送负载,(指定 "mutable-content":1),与移动端约定指定的键值,这里我们采用的数据格式是
{
"aps":{
"alert":{
"title":"iOS 10 title",
"subtitle":"iOS 10 subtitle",
"body":"iOS 10 body"
},
"my-attachment":"https://qlogo4.store.qq.com/qzone/576014231/576014231/50?1552974221",
"mutable-content":1,
"category":"myNotificationCategory1",
"sound":"default",
"badge":3
}
}
测试方式通过使用 Easy APNs Provider. App Store搜索可以直接下载,使用方式简单,添加token及证书即可.
tip: 添加token时,可以直接获取设备的deviceToken(Data类型),直接输出其string类型后去掉尖括号和空格即可.
移动端
通过添加新的target( NotificationServiceExtension), 在 didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)
方法中将下载好的资源,装载进attachments中.
代码如下
import UserNotifications
import UIKit
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]"
if let aps = bestAttemptContent.userInfo["aps"] as? [String: Any], let imageUrlString = aps["my-attachment"] as? String, let imageUrl = URL(string: imageUrlString) {
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: imageUrl) { [weak self](data, response, error) in
guard let self = self else { return }
if let _ = error {
}
else {
let path = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first! + "/logo.png"
if let data = data, let image = UIImage(data: data) {
let imageData = image.jpegData(compressionQuality: 0.1)
do {
try imageData?.write(to: URL(fileURLWithPath: path), options: .atomic)
}
catch {
debugPrint(error.localizedDescription)
}
}
do {
let attachment = try UNNotificationAttachment(identifier: "remote-attachImage", url: URL(fileURLWithPath: path), options: nil)
self.bestAttemptContent?.attachments = [attachment]
} catch {
debugPrint(error.localizedDescription)
}
}
self.contentHandler?(bestAttemptContent)
}
task.resume()
}
}
}
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)
}
}
}
调试
将target调为自己创建的NotificationService,选择Xcode的 Debug->Attach to Process by PID or Name, 然后 PID or Name项填入创建的Service的名称. 点击Attach.
然后点击运行,选择依附的app.
现在就可以在程序进入后台的时候,用 Easy APNs Provider 发送推送. 然后可以在 didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)
中打断点 进行调试