NotificationService.swift (3005B)
1 // 2 // NotificationService.swift 3 // DamusNotificationService 4 // 5 // Created by Daniel D’Aquino on 2023-11-10. 6 // 7 8 import UserNotifications 9 import Foundation 10 11 class NotificationService: UNNotificationServiceExtension { 12 13 var contentHandler: ((UNNotificationContent) -> Void)? 14 var bestAttemptContent: UNMutableNotificationContent? 15 16 override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { 17 self.contentHandler = contentHandler 18 19 guard let nostr_event_json = request.content.userInfo["nostr_event"] as? String, 20 let nostr_event = NdbNote.owned_from_json(json: nostr_event_json) 21 else { 22 // No nostr event detected. Just display the original notification 23 contentHandler(request.content) 24 return; 25 } 26 27 // Log that we got a push notification 28 Log.debug("Got nostr event push notification from pubkey %s", for: .push_notifications, nostr_event.pubkey.hex()) 29 30 guard let state = NotificationExtensionState(), 31 let display_name = state.ndb.lookup_profile(nostr_event.pubkey)?.unsafeUnownedValue?.profile?.display_name // We are not holding the txn here. 32 else { 33 // Something failed to initialize so let's go for the next best thing 34 guard let improved_content = NotificationFormatter.shared.format_message(event: nostr_event) else { 35 // We cannot format this nostr event. Suppress notification. 36 contentHandler(UNNotificationContent()) 37 return 38 } 39 contentHandler(improved_content) 40 return 41 } 42 43 guard should_display_notification(state: state, event: nostr_event) else { 44 // We should not display notification for this event. Suppress notification. 45 contentHandler(UNNotificationContent()) 46 return 47 } 48 49 guard let notification_object = generate_local_notification_object(from: nostr_event, state: state) else { 50 // We could not process this notification. Probably an unsupported nostr event kind. Suppress. 51 contentHandler(UNNotificationContent()) 52 return 53 } 54 55 Task { 56 if let (improvedContent, _) = await NotificationFormatter.shared.format_message(displayName: display_name, notify: notification_object, state: state) { 57 contentHandler(improvedContent) 58 } 59 } 60 } 61 62 override func serviceExtensionTimeWillExpire() { 63 // Called just before the extension will be terminated by the system. 64 // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. 65 if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { 66 contentHandler(bestAttemptContent) 67 } 68 } 69 70 }