field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | LICENSE

FieldBackgroundURLSessionEvents.swift (1971B)


      1 import Foundation
      2 
      3 actor FieldBackgroundURLSessionEvents {
      4     static let shared = FieldBackgroundURLSessionEvents()
      5 
      6     private var backgroundExecution: FieldBackgroundExecution?
      7     private var pendingEvents: [FieldPendingBackgroundURLSessionEvent]
      8     private var completesImmediately: Bool
      9 
     10     private init() {
     11         self.pendingEvents = []
     12         self.completesImmediately = false
     13     }
     14 
     15     func attach(_ backgroundExecution: FieldBackgroundExecution) async {
     16         self.backgroundExecution = backgroundExecution
     17         completesImmediately = false
     18         let events = pendingEvents
     19         pendingEvents = []
     20         for event in events {
     21             await backgroundExecution.handleEventsForBackgroundURLSession(
     22                 identifier: event.identifier,
     23                 completionHandler: event.completionHandler
     24             )
     25         }
     26     }
     27 
     28     func handleEvents(
     29         identifier: String,
     30         completionHandler: @escaping @Sendable () -> Void
     31     ) async {
     32         guard !completesImmediately else {
     33             completionHandler()
     34             return
     35         }
     36         guard let backgroundExecution else {
     37             pendingEvents.append(
     38                 FieldPendingBackgroundURLSessionEvent(
     39                     identifier: identifier,
     40                     completionHandler: completionHandler
     41                 )
     42             )
     43             return
     44         }
     45         await backgroundExecution.handleEventsForBackgroundURLSession(
     46             identifier: identifier,
     47             completionHandler: completionHandler
     48         )
     49     }
     50 
     51     func completePendingAfterStartupFailure() {
     52         backgroundExecution = nil
     53         completesImmediately = true
     54         let events = pendingEvents
     55         pendingEvents = []
     56         for event in events {
     57             event.completionHandler()
     58         }
     59     }
     60 }
     61 
     62 private struct FieldPendingBackgroundURLSessionEvent: Sendable {
     63     let identifier: String
     64     let completionHandler: @Sendable () -> Void
     65 }