TalerWallet1App.swift (4172B)
1 /* 2 * This file is part of GNU Taler, ©2022-25 Taler Systems S.A. 3 * See LICENSE.md 4 */ 5 /** 6 * Main app entry point 7 * 8 * @author Jonathan Buchanan 9 * @author Marc Stibane 10 */ 11 import BackgroundTasks 12 import SwiftUI 13 import os.log 14 import SymLog 15 16 @main 17 struct TalerWallet1App: App { 18 private let symLog = SymLogV() 19 @Environment(\.scenePhase) private var phase 20 @StateObject private var viewState = ViewState.shared // popToRootView() 21 @StateObject private var viewState2 = ViewState2.shared // popToRootView() 22 @State private var soundPlayed = false 23 24 private let walletCore = WalletCore.shared 25 private let controller = Controller.shared 26 private let model = WalletModel.shared 27 private let debugViewC = DebugViewC.shared 28 let logger = Logger(subsystem: "net.taler.gnu", category: "Main App") 29 private let biometricService = BiometricService.shared 30 31 func scheduleAppRefresh() { 32 let request = BGAppRefreshTaskRequest(identifier: "net.taler.gnu.refresh") 33 request.earliestBeginDate = .now.addingTimeInterval(24 * 3600) 34 try? BGTaskScheduler.shared.submit(request) 35 } 36 37 var body: some Scene { 38 WindowGroup { 39 MainView(logger: logger, stack: CallStack("App"), soundPlayed: $soundPlayed) 40 .environmentObject(debugViewC) // change viewID / sheetID 41 .environmentObject(viewState) // popToRoot 42 .environmentObject(viewState2) // popToRoot 43 .environmentObject(controller) 44 .environmentObject(model) 45 .environmentObject(biometricService) 46 .addKeyboardVisibilityToEnvironment() 47 /// external events are taler:// or payto:// URLs passed to this app 48 /// we handle them in .onOpenURL in MainView.swift 49 .handlesExternalEvents(preferring: ["*"], allowing: ["*"]) 50 .task { 51 try! await controller.initWalletCore(model, setTesting: false) // will (and should) crash on failure 52 } 53 } 54 .onChange(of: phase) { newPhase in 55 switch newPhase { 56 case .active: 57 logger.log("❗️.onChange() ==> Active") 58 case .background: 59 logger.log("❗️.onChange() ==> Background)") 60 // scheduleAppRefresh() 61 default: break 62 } 63 } 64 // if #available(iOS 16.4, *) { 65 // .backgroundTask(.appRefresh("net.taler.refresh")) { 66 // symLog.log("backgroundTask running") 67 //#if 0 68 // let request = URLRequest(url: URL(string: "your_backend")!) 69 // guard let data = try? await URLSession.shared.data(for: request).0 else { 70 // return 71 // } 72 // 73 // let decoder = JSONDecoder() 74 // guard let products = try? decoder.decode([Product].self, from: data) else { 75 // return 76 // } 77 // 78 // if !products.isEmpty && !Task.isCancelled { 79 // await notifyUser(for: products) 80 // } 81 //#endif 82 // } 83 // } else { 84 // // Fallback on earlier versions 85 // } 86 87 } 88 } 89 90 final class ViewState : ObservableObject { 91 static let shared = ViewState() 92 @Published var rootViewId = UUID() 93 let logger = Logger(subsystem: "net.taler.gnu", category: "ViewState") 94 95 public func popToRootView(_ stack: CallStack?) -> Void { 96 logger.info("popToRootView") 97 rootViewId = UUID() // setting a new ID will cause 1st NavStack popToRootView behaviour 98 } 99 100 private init() { } 101 } 102 103 final class ViewState2 : ObservableObject { 104 static let shared = ViewState2() 105 @Published var rootViewId = UUID() 106 let logger = Logger(subsystem: "net.taler.gnu", category: "ViewState2") 107 108 public func popToRootView(_ stack: CallStack?) -> Void { 109 logger.info("popToRootView") 110 rootViewId = UUID() // setting a new ID will cause 2nd NavStack popToRootView behaviour 111 } 112 113 private init() { } 114 }