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 }