forked from arnesson/cordova-plugin-firebase
-
-
Notifications
You must be signed in to change notification settings - Fork 473
/
NotificationService.swift
108 lines (98 loc) · 5.08 KB
/
NotificationService.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
guard let content = bestAttemptContent else {
#if DEBUG
exitGracefully("bestAttemptContent not a UNMutableNotificationContent")
#endif
return
}
DispatchQueue.main.async { [weak self] in
let userInfo: [AnyHashable: Any] = request.content.userInfo
content.attachments = self?.attachmentsFor(userInfo) ?? []
guard let copy = self?.bestAttemptContent else {
#if DEBUG
self?.exitGracefully("bestAttemptContent is nil")
#endif
return
}
contentHandler(copy)
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler, let content = self.bestAttemptContent {
contentHandler(content)
}
}
/// Helper function to extract Attachments from an userInfo object
///
/// - Attribute userInfo: The user info extracted from the notification,
/// which should contain one of the available keys to create
/// a rich push notification.
private func attachmentsFor(_ userInfo: [AnyHashable: Any]) -> [UNNotificationAttachment] {
if let attachmentURLString = userInfo["notification_ios_image_png"] as? String {
guard let attachmentURL = URL(string: attachmentURLString),
let imageData = try? Data(contentsOf: attachmentURL),
let attachment = self.save("image.png", data: imageData, options: nil) else {
#if DEBUG
self.exitGracefully("PNG was not saved properly")
#endif
return []
}
return [attachment]
} else if let attachmentURLString = userInfo["notification_ios_image_jpg"] as? String {
guard let attachmentURL = URL(string: attachmentURLString),
let imageData = try? Data(contentsOf: attachmentURL),
let attachment = self.save("image.jpg", data: imageData, options: nil) else {
#if DEBUG
self.exitGracefully("JPG was not saved properly")
#endif
return []
}
return [attachment]
} else if let attachmentURLString = userInfo["notification_ios_image_gif"] as? String {
guard let attachmentURL = URL(string: attachmentURLString),
let imageData = try? Data(contentsOf: attachmentURL),
let attachment = self.save("image.gif", data: imageData, options: nil) else {
#if DEBUG
self.exitGracefully("GIF was not saved properly")
#endif
return []
}
return [attachment]
}
return []
}
/// Save data object onto disk and return an optional attachment linked to this path.
///
/// - Attributes:
/// - identifier: The unique identifier of the attachment.
/// Use this string to identify the attachment later. If you specify an
/// empty string, this method creates a unique identifier string for you.
/// - data: The data stored onto disk.
/// - options: A dictionary of options related to the attached file.
/// Use the options to specify meta information about the attachment,
/// such as the clipping rectangle to use for the resulting thumbnail.
private func save(_ identifier: String, data: Data, options: [AnyHashable: Any]?) -> UNNotificationAttachment? {
// Create paths
let directory = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString, isDirectory: true)
let fileURL = directory.appendingPathComponent(identifier)
// Write data on disk
try? FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true, attributes: nil)
try? data.write(to: fileURL, options: [])
// Create Notification attachment
return try? UNNotificationAttachment(identifier: identifier, url: fileURL, options: options)
}
/// Something went wrong, so maybe we want to clean up and present a fallback to the user.
///
/// - Attribute reason: The reason why something went wrong.
private func exitGracefully(_ reason: String = "") {
guard let copy = bestAttemptContent?.mutableCopy() as? UNMutableNotificationContent else { return }
copy.title = reason
contentHandler?(copy)
}
}