Created
March 6, 2018 07:32
-
-
Save acalism/a09c8c2ac6c72e9a8faf2a9fc70fafe9 to your computer and use it in GitHub Desktop.
App Extension: Notification Service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UserNotifications | |
import MobileCoreServices | |
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 = "[modified] \(bestAttemptContent.title)" | |
tryToFetchAttachment(attemptContent: bestAttemptContent, contentHandler: 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 { | |
// Modify the notification content here... | |
tryToFetchAttachment(attemptContent: bestAttemptContent, contentHandler: contentHandler) // 如果两次都失败,该通知最终还是会显示的,只是没有 attachment 罢了。 | |
} | |
} | |
// 消息体顶层填入 image 参数及其指向的图片 url(若不用 https,需在 info.plist 里设置 Allow Arbitrary Loads 为 YES) | |
private func tryToFetchAttachment(attemptContent: UNMutableNotificationContent, contentHandler: @escaping (UNNotificationContent) -> Void) { | |
// Modify the notification content here... | |
guard let s = attemptContent.userInfo[AnyHashable("image")] as? String, let imageURL = URL(string: s) else { | |
contentHandler(attemptContent) | |
return | |
} | |
URLSession.shared.downloadTask(with: imageURL, completionHandler: { (url, response, error) in | |
guard error == nil, let fileURL = url else { | |
return | |
} | |
guard let attachment = try? UNNotificationAttachment(identifier: response?.suggestedFilename ?? "image.jpeg", file: FileObject.cacheURL(fileURL), options: nil) else { | |
return | |
} | |
attemptContent.attachments = [attachment] | |
contentHandler(attemptContent) | |
}).resume() | |
} | |
} | |
enum FileObject { | |
case data(Data) | |
case cacheURL(URL) | |
} | |
extension UNNotificationAttachment { | |
/// Save the image to disk, or move cache file to tmp file | |
convenience init(identifier: String, file: FileObject, options: [AnyHashable : Any]?) throws { | |
let attachSubFolderName = ProcessInfo.processInfo.globallyUniqueString | |
let attachSubFolderURL = URL.init(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(attachSubFolderName, isDirectory: true) | |
let attachFileURL = attachSubFolderURL.appendingPathComponent(identifier) | |
try FileManager.default.createDirectory(at: attachSubFolderURL, withIntermediateDirectories: true, attributes: nil) | |
switch file { | |
case .cacheURL(let cacheFileURL): // 转移 | |
try FileManager.default.copyItem(at: cacheFileURL, to: attachFileURL) | |
case .data(let data): // 保存为文件 | |
try data.write(to: attachFileURL, options: []) | |
} | |
try self.init(identifier: identifier, url: attachFileURL, options: options) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment