From 286dad9d4811bc2bdfb0678541657b320b1cc662 Mon Sep 17 00:00:00 2001 From: sanj-tyro <87962819+sanj-tyro@users.noreply.github.com> Date: Fri, 17 May 2024 16:13:58 +1000 Subject: [PATCH] add content view model to top of app (#28) --- SampleApp/SampleApp/SampleApp.swift | 7 ++-- .../ViewModels/ContentViewModel.swift | 34 +++++++++---------- SampleApp/SampleApp/Views/ContentView.swift | 14 +------- 3 files changed, 22 insertions(+), 33 deletions(-) diff --git a/SampleApp/SampleApp/SampleApp.swift b/SampleApp/SampleApp/SampleApp.swift index ffa67f5..660ef91 100644 --- a/SampleApp/SampleApp/SampleApp.swift +++ b/SampleApp/SampleApp/SampleApp.swift @@ -12,13 +12,16 @@ import TyroTapToPaySDK struct SampleApp: App { @Environment(\.scenePhase) private var scenePhase: ScenePhase @ObservedObject var tapToPaySdk: TyroTapToPay + private var contentViewModel: ContentViewModel init() { do { - tapToPaySdk = try TyroTapToPay( + let tapToPaySdk = try TyroTapToPay( environment: .sandbox, connectionProvider: DemoConnectionProvider() ) + contentViewModel = ContentViewModel(tapToPaySdk: tapToPaySdk) + self.tapToPaySdk = tapToPaySdk } catch { fatalError(error.localizedDescription) } @@ -31,7 +34,7 @@ struct SampleApp: App { .aspectRatio(contentMode: .fit) .frame(maxWidth: 100) .padding() - ContentView(viewModel: ContentViewModel(tapToPaySdk: self.tapToPaySdk)) + ContentView(viewModel: contentViewModel) } } } diff --git a/SampleApp/SampleApp/ViewModels/ContentViewModel.swift b/SampleApp/SampleApp/ViewModels/ContentViewModel.swift index 0b6f8e6..d67ea35 100644 --- a/SampleApp/SampleApp/ViewModels/ContentViewModel.swift +++ b/SampleApp/SampleApp/ViewModels/ContentViewModel.swift @@ -17,38 +17,36 @@ class ContentViewModel: ObservableObject { init(tapToPaySdk: TyroTapToPay) { self.tapToPaySdk = tapToPaySdk - } - func showError(errorMessage: String) { - state = .error(errorMessage) + Task(priority: .userInitiated) { [weak self] in + await self?.connect() + } } - func connect() async throws { + func connect() async { do { - DispatchQueue.main.async { + await MainActor.run { self.state = .loading("Connecting to reader...") } try await self.tapToPaySdk.connect() - DispatchQueue.main.async { + await MainActor.run { self.state = .ready self.isConnected = true } } catch { - DispatchQueue.main.async { + await MainActor.run { self.state = .error(error.localizedDescription) } } } func reset() { - DispatchQueue.main.async { - self.state = .ready - self.transactionOutcome = nil - } + state = .ready + transactionOutcome = nil } func startPayment(_ transactionType: TransactionType, _ amount: Decimal) async throws { - DispatchQueue.main.async { + await MainActor.run { self.state = .loading("Processing \(transactionType.rawValue.lowercased())...") } let transactionDetail = TransactionDetail( @@ -67,28 +65,28 @@ class ContentViewModel: ObservableObject { transactionType == .payment ? try await self.tapToPaySdk.startPayment(transactionDetail: transactionDetail) : try await self.tapToPaySdk.refundPayment(transactionDetail: transactionDetail) - DispatchQueue.main.async { + await MainActor.run { self.state = .success(outcome) self.transactionOutcome = outcome } } catch TapToPaySDKError.failedToVerifyConnection { - DispatchQueue.main.async { + await MainActor.run { self.state = .error("failedToVerifyConnection") } } catch TapToPaySDKError.transactionError(let errorMessage) { - DispatchQueue.main.async { + await MainActor.run { self.state = .error("transactionError: \(errorMessage)") } } catch TapToPaySDKError.unableToConnectReader { - DispatchQueue.main.async { + await MainActor.run { self.state = .error("unableToConnectReader") } } catch TapToPaySDKError.invalidParameter(let errorMessage) { - DispatchQueue.main.async { + await MainActor.run { self.state = .error("invalidParameter: \(errorMessage)") } } catch { - DispatchQueue.main.async { + await MainActor.run { self.state = .error(error.localizedDescription) } } diff --git a/SampleApp/SampleApp/Views/ContentView.swift b/SampleApp/SampleApp/Views/ContentView.swift index fd0dfbd..0f94ba5 100644 --- a/SampleApp/SampleApp/Views/ContentView.swift +++ b/SampleApp/SampleApp/Views/ContentView.swift @@ -18,8 +18,7 @@ enum LoadingState { struct ContentView: View { @Environment(\.scenePhase) var scenePhase @StateObject private var viewModel: ContentViewModel - @State private var firstLoad = true - + init(viewModel: ContentViewModel) { _viewModel = StateObject(wrappedValue: viewModel) } @@ -72,16 +71,5 @@ struct ContentView: View { await self.viewModel.tapToPaySdk.didChange(scenePhase: newValue) } } - .task { - guard firstLoad else { - return - } - firstLoad = false - do { - try await viewModel.connect() - } catch { - viewModel.showError(errorMessage: error.localizedDescription) - } - } } }