taler-ios

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

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 }