damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

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 }