taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

TalerWallet1App.swift (4276B)


      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 #if DEBUG
     52                     let testing = true
     53 #else
     54                     let testing = false
     55 #endif
     56                     try! await controller.initWalletCore(model, setTesting: testing)     // will (and should) crash on failure
     57                 }
     58         }
     59         .onChange(of: phase) { newPhase in
     60             switch newPhase {
     61                 case .active:
     62                     logger.log("❗️.onChange() ==> Active")
     63                 case .background:
     64                     logger.log("❗️.onChange() ==> Background)")
     65 //                    scheduleAppRefresh()
     66                 default: break
     67             }
     68         }
     69 //        if #available(iOS 16.4, *) {
     70 //            .backgroundTask(.appRefresh("net.taler.refresh")) {
     71 //                symLog.log("backgroundTask running")
     72 //#if 0
     73 //                let request = URLRequest(url: URL(string: "your_backend")!)
     74 //                guard let data = try? await URLSession.shared.data(for: request).0 else {
     75 //                    return
     76 //                }
     77 //                
     78 //                let decoder = JSONDecoder()
     79 //                guard let products = try? decoder.decode([Product].self, from: data) else {
     80 //                    return
     81 //                }
     82 //                
     83 //                if !products.isEmpty && !Task.isCancelled {
     84 //                    await notifyUser(for: products)
     85 //                }
     86 //#endif
     87 //            }
     88 //        } else {
     89 //            // Fallback on earlier versions
     90 //        }
     91 
     92     }
     93 }
     94 
     95 final class ViewState : ObservableObject {
     96     static let shared = ViewState()
     97     @Published var rootViewId = UUID()
     98     let logger = Logger(subsystem: "net.taler.gnu", category: "ViewState")
     99 
    100     public func popToRootView(_ stack: CallStack?) -> Void {
    101         logger.info("popToRootView")
    102         rootViewId = UUID() // setting a new ID will cause 1st NavStack popToRootView behaviour
    103     }
    104 
    105     private init() { }
    106 }
    107 
    108 final class ViewState2 : ObservableObject {
    109     static let shared = ViewState2()
    110     @Published var rootViewId = UUID()
    111     let logger = Logger(subsystem: "net.taler.gnu", category: "ViewState2")
    112 
    113     public func popToRootView(_ stack: CallStack?) -> Void {
    114         logger.info("popToRootView")
    115         rootViewId = UUID() // setting a new ID will cause 2nd NavStack popToRootView behaviour
    116     }
    117 
    118     private init() { }
    119 }