Skip to content

Instantly share code, notes, and snippets.

@tadija
Last active October 26, 2021 18:41
Show Gist options
  • Save tadija/535f88d01ef0d779ed955205ca2ab242 to your computer and use it in GitHub Desktop.
Save tadija/535f88d01ef0d779ed955205ca2ab242 to your computer and use it in GitHub Desktop.
AEUserNotification
/**
* https://gist.github.com/tadija/535f88d01ef0d779ed955205ca2ab242
* Revision 7
* Copyright © 2018-2021 Marko Tadić
* Licensed under the MIT license
*/
import UserNotifications
public struct UserNotification {
public let userInfo: [AnyHashable: Any]
public let aps: Payload
public var content = UNMutableNotificationContent()
public struct Payload {
public struct Alert {
public let title: String?
public let subtitle: String?
public let body: String?
}
public let alert: Alert?
public let badge: Int?
public let sound: String?
public let category: String?
public let thread: String?
public let targetContent: String?
public let contentAvailable: Int?
public let mutableContent: Int?
public init(userInfo: [AnyHashable: Any]) {
let aps = userInfo["aps"] as? [AnyHashable: Any]
let alertData = aps?["alert"] as? [AnyHashable: Any]
alert = Alert(
title: alertData?["title"] as? String,
subtitle: alertData?["subtitle"] as? String,
body: alertData?["body"] as? String
)
badge = aps?["badge"] as? Int
sound = aps?["sound"] as? String
category = aps?["category"] as? String
thread = aps?["thread-id"] as? String
targetContent = aps?["target-content-id"] as? String
contentAvailable = aps?["content-available"] as? Int
mutableContent = aps?["mutable-content"] as? Int
}
}
public init(userInfo: [AnyHashable: Any]) {
self.userInfo = userInfo
self.aps = Payload(userInfo: userInfo)
updateContent()
}
public init(_ notification: UNNotification) {
self.init(userInfo: notification.request.content.userInfo)
}
private func updateContent() {
content.userInfo = userInfo
if let title = aps.alert?.title {
content.title = title
}
if let subtitle = aps.alert?.subtitle {
content.subtitle = subtitle
}
if let body = aps.alert?.body {
content.body = body
}
if let badge = aps.badge {
content.badge = NSNumber(value: badge)
}
if let sound = aps.sound {
content.sound = UNNotificationSound(
named: UNNotificationSoundName(rawValue: sound)
)
}
if let category = aps.category {
content.categoryIdentifier = category
}
if let thread = aps.thread {
content.threadIdentifier = thread
}
if #available(iOS 13.0, *),
let targetContent = aps.targetContent {
content.targetContentIdentifier = targetContent
}
}
}
public extension UserNotification {
init?(apnsFile name: String) {
guard
let url = Bundle.main.url(forResource: name, withExtension: "apns"),
let data = try? Data(contentsOf: url, options: .mappedIfSafe),
let json = try? JSONSerialization
.jsonObject(with: data, options: .mutableContainers),
let userInfo = json as? [AnyHashable: Any]
else {
return nil
}
self = UserNotification(userInfo: userInfo)
}
static func sendLocal(
content: UNNotificationContent,
via center: UNUserNotificationCenter = .current(),
trigger: UNNotificationTrigger = defaultLocalTrigger,
then completion: ((Error?) -> Void)? = nil)
{
let request = UNNotificationRequest(
identifier: content.categoryIdentifier,
content: content,
trigger: trigger
)
center.add(request, withCompletionHandler: completion)
}
static var defaultLocalTrigger: UNNotificationTrigger =
UNTimeIntervalNotificationTrigger(
timeInterval: 3,
repeats: false
)
static func tokenString(from data: Data) -> String {
/// - SEE: http://stackoverflow.com/a/24979958/2165585
var token: String = ""
for i in 0..<data.count {
token += String(format: "%02.2hhx", data[i] as CVarArg)
}
return token
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment