commit 8ba44768bb3869261b902b25076f7e5bce8401ba parent 7cecef9af7fac6be732c7983f34fd3ca0fcc4200 Author: Iván Ávalos <avalos@disroot.org> Date: Fri, 5 Apr 2024 22:30:37 -0600 Centralize all error handling in the model Diffstat:
42 files changed, 262 insertions(+), 439 deletions(-)
diff --git a/TalerWallet1/Model/Model+Balances.swift b/TalerWallet1/Model/Model+Balances.swift @@ -54,13 +54,13 @@ fileprivate struct Balances: WalletBackendFormattedRequest { // MARK: - extension WalletModel { /// fetch Balances from Wallet-Core. No networking involved - @MainActor func balancesM(_ stack: CallStack) + @MainActor func balancesM(_ stack: CallStack, viewHandles: Bool = false) async throws -> [Balance] { // M for MainActor await semaphore.wait() defer { semaphore.signal() } if cachedBalances == nil { let request = Balances() - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) cachedBalances = response.balances } else { logger.trace("returning cached Balances") diff --git a/TalerWallet1/Model/Model+Deposit.swift b/TalerWallet1/Model/Model+Deposit.swift @@ -74,27 +74,27 @@ fileprivate struct CreateDepositGroup: WalletBackendFormattedRequest { extension WalletModel { /// validate IBAN @MainActor - func validateIbanM(_ iban: String) // M for MainActor + func validateIbanM(_ iban: String, viewHandles: Bool = false) // M for MainActor async throws -> Bool { let request = ValidateIban(iban: iban) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response.valid } /// deposit coins. Networking involved @MainActor - func prepareDepositM(_ depositPaytoUri: String, amount: Amount) // M for MainActor + func prepareDepositM(_ depositPaytoUri: String, amount: Amount, viewHandles: Bool = false) // M for MainActor async throws -> PrepareDepositResult { let request = PrepareDeposit(depositPaytoUri: depositPaytoUri, amount: amount) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @MainActor - func createDepositGroupM(_ depositPaytoUri: String, amount: Amount) // M for MainActor + func createDepositGroupM(_ depositPaytoUri: String, amount: Amount, viewHandles: Bool = false) // M for MainActor async throws -> DepositGroupResult { let request = CreateDepositGroup(depositPaytoUri: depositPaytoUri, amount: amount) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } diff --git a/TalerWallet1/Model/Model+Exchange.swift b/TalerWallet1/Model/Model+Exchange.swift @@ -156,11 +156,11 @@ fileprivate struct GetCurrencySpecification: WalletBackendFormattedRequest { // MARK: - extension WalletModel { /// ask wallet-core for its list of known exchanges - @MainActor func listExchangesForScopedCurrencyM(scope: ScopeInfo) + @MainActor func listExchangesForScopedCurrencyM(scope: ScopeInfo, viewHandles: Bool = false) async -> [ExchangeUrlItem] { // M for MainActor do { let request = ListExchangesForScopedCurrency(scope: scope) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response.exchanges } catch { return [] // empty, but not nil @@ -168,45 +168,47 @@ extension WalletModel { } /// ask wallet-core for its list of known exchanges - @MainActor func listExchangesM(devMode: Bool = false) + @MainActor func listExchangesM(devMode: Bool = false, viewHandles: Bool = false) async throws -> [Exchange] { // M for MainActor let request = ListExchanges() - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response.exchanges } /// add a new exchange with URL to the wallet's list of known exchanges - func getExchangeByUrl(url: String) + func getExchangeByUrl(url: String, viewHandles: Bool = false) async throws -> Exchange { let request = GetExchangeByUrl(exchangeBaseUrl: url) // logger.info("query for exchange: \(url, privacy: .public)") - let response = try await sendRequest(request) + let response = try await sendRequest(request, viewHandles: viewHandles) return response } /// add a new exchange with URL to the wallet's list of known exchanges - func addExchange(url: String) + func addExchange(url: String, viewHandles: Bool = false) async throws { let request = AddExchange(exchangeBaseUrl: url) logger.info("adding exchange: \(url, privacy: .public)") - _ = try await sendRequest(request) + _ = try await sendRequest(request, viewHandles: viewHandles) } /// ask wallet-core to update an existing exchange by querying it for denominations, fees, and scoped currency info // func updateExchange(scopeInfo: ScopeInfo) - func updateExchange(exchangeBaseUrl: String) +// func updateExchange(scopeInfo: ScopeInfo, viewHandles: Bool = false) + func updateExchange(exchangeBaseUrl: String, viewHandles: Bool = false) async throws { // let request = UpdateExchange(scopeInfo: scopeInfo) let request = UpdateExchange(exchangeBaseUrl: exchangeBaseUrl) +// logger.info("updating exchange for: \(scopeInfo.currency, privacy: .public)") logger.info("updating exchange: \(exchangeBaseUrl, privacy: .public)") - _ = try await sendRequest(request) + _ = try await sendRequest(request, viewHandles: viewHandles) } @MainActor - func getCurrencyInfoM(scope: ScopeInfo, delay: UInt = 0) + func getCurrencyInfoM(scope: ScopeInfo, delay: UInt = 0, viewHandles: Bool = false) async throws -> CurrencyInfo { let request = GetCurrencySpecification(scope: scope) - let response = try await sendRequest(request, ASYNCDELAY + delay) + let response = try await sendRequest(request, ASYNCDELAY + delay, viewHandles: viewHandles) return CurrencyInfo(scope: scope, specs: response.currencySpecification, formatter: CurrencyFormatter.formatter(scope: scope, specs: response.currencySpecification)) diff --git a/TalerWallet1/Model/Model+P2P.swift b/TalerWallet1/Model/Model+P2P.swift @@ -32,10 +32,10 @@ fileprivate struct GetMaxPeerPushAmount: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func getMaxPeerPushAmountM(_ currency: String) // M for MainActor + func getMaxPeerPushAmountM(_ currency: String, viewHandles: Bool = false) // M for MainActor async throws -> AmountResponse { let request = GetMaxPeerPushAmount(currency: currency) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // getMaxPeerPushAmountM @@ -58,10 +58,10 @@ fileprivate struct CheckPeerPushDebit: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func checkPeerPushDebitM(_ amount: Amount) // M for MainActor + func checkPeerPushDebitM(_ amount: Amount, viewHandles: Bool = false) // M for MainActor async throws -> CheckPeerPushDebitResponse { let request = CheckPeerPushDebit(amount: amount) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // checkPeerPushDebitM @@ -90,11 +90,11 @@ fileprivate struct InitiatePeerPushDebit: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func initiatePeerPushDebitM(_ baseURL: String?, terms: PeerContractTerms) // M for MainActor + func initiatePeerPushDebitM(_ baseURL: String?, terms: PeerContractTerms, viewHandles: Bool = false) // M for MainActor async throws -> InitiatePeerPushDebitResponse { let request = InitiatePeerPushDebit(exchangeBaseUrl: baseURL, partialContractTerms: terms) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // initiatePeerPushDebitM @@ -123,10 +123,10 @@ fileprivate struct CheckPeerPullCredit: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func checkPeerPullCreditM(_ amount: Amount, exchangeBaseUrl: String?) // M for MainActor + func checkPeerPullCreditM(_ amount: Amount, exchangeBaseUrl: String?, viewHandles: Bool = false) // M for MainActor async throws -> CheckPeerPullCreditResponse { let request = CheckPeerPullCredit(exchangeBaseUrl: exchangeBaseUrl, amount: amount) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // checkPeerPullCreditM @@ -151,11 +151,11 @@ fileprivate struct InitiatePeerPullCredit: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func initiatePeerPullCreditM(_ baseURL: String?, terms: PeerContractTerms) // M for MainActor + func initiatePeerPullCreditM(_ baseURL: String?, terms: PeerContractTerms, viewHandles: Bool = false) // M for MainActor async throws -> InitiatePeerPullCreditResponse { let request = InitiatePeerPullCredit(exchangeBaseUrl: baseURL, partialContractTerms: terms) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // initiatePeerPullCreditM @@ -181,10 +181,10 @@ fileprivate struct PreparePeerPushCredit: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func preparePeerPushCreditM(_ talerUri: String) // M for MainActor + func preparePeerPushCreditM(_ talerUri: String, viewHandles: Bool = false) // M for MainActor async throws -> PreparePeerPushCreditResponse { let request = PreparePeerPushCredit(talerUri: talerUri) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // preparePeerPushCreditM @@ -202,10 +202,10 @@ fileprivate struct AcceptPeerPushCredit: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func acceptPeerPushCreditM(_ transactionId: String) // M for MainActor + func acceptPeerPushCreditM(_ transactionId: String, viewHandles: Bool = false) // M for MainActor async throws -> Decodable { let request = AcceptPeerPushCredit(transactionId: transactionId) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // acceptPeerPushCreditM @@ -230,10 +230,10 @@ fileprivate struct PreparePeerPullDebit: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func preparePeerPullDebitM(_ talerUri: String) // M for MainActor + func preparePeerPullDebitM(_ talerUri: String, viewHandles: Bool = false) // M for MainActor async throws -> PreparePeerPullDebitResponse { let request = PreparePeerPullDebit(talerUri: talerUri) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // preparePeerPullDebitM @@ -251,10 +251,10 @@ fileprivate struct ConfirmPeerPullDebit: WalletBackendFormattedRequest { } extension WalletModel { @MainActor - func confirmPeerPullDebitM(_ transactionId: String) // M for MainActor + func confirmPeerPullDebitM(_ transactionId: String, viewHandles: Bool = false) // M for MainActor async throws -> Decodable { let request = ConfirmPeerPullDebit(transactionId: transactionId) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } // confirmPeerPullDebitM diff --git a/TalerWallet1/Model/Model+Payment.swift b/TalerWallet1/Model/Model+Payment.swift @@ -197,25 +197,25 @@ fileprivate struct confirmPayForUri: WalletBackendFormattedRequest { extension WalletModel { /// load payment details. Networking involved @MainActor - func preparePayForUriM(_ talerPayUri: String) // M for MainActor + func preparePayForUriM(_ talerPayUri: String, viewHandles: Bool = false) // M for MainActor async throws -> PreparePayResult { let request = PreparePayForUri(talerPayUri: talerPayUri) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @MainActor - func preparePayForTemplateM(_ talerPayTemplateUri: String, amount: Amount?, summary: String?) // M for MainActor + func preparePayForTemplateM(_ talerPayTemplateUri: String, amount: Amount?, summary: String?, viewHandles: Bool = false) // M for MainActor async throws -> PreparePayResult { let templateParams = TemplateParams(amount: amount, summary: summary) let request = PreparePayForTemplate(talerPayTemplateUri: talerPayTemplateUri, templateParams: templateParams) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @MainActor - func confirmPayM(_ transactionId: String) // M for MainActor + func confirmPayM(_ transactionId: String, viewHandles: Bool = false) // M for MainActor async throws -> ConfirmPayResult { let request = confirmPayForUri(transactionId: transactionId) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } diff --git a/TalerWallet1/Model/Model+Pending.swift b/TalerWallet1/Model/Model+Pending.swift @@ -42,10 +42,10 @@ struct PendingOperation: Codable, Hashable { } // MARK: - extension WalletModel { - @MainActor func getPendingOperationsM() + @MainActor func getPendingOperationsM(viewHandles: Bool = false) async throws -> [PendingOperation] { // M for MainActor let request = GetPendingOperations() - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response.pendingOperations } } diff --git a/TalerWallet1/Model/Model+Refund.swift b/TalerWallet1/Model/Model+Refund.swift @@ -40,15 +40,15 @@ struct StartRefundQueryRequest: WalletBackendFormattedRequest { // MARK: - extension WalletModel { @MainActor - func startRefundForUriM(url: String) async throws -> String { + func startRefundForUriM(url: String, viewHandles: Bool = false) async throws -> String { let request = StartRefundURIRequest(talerRefundUri: url) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response.transactionId } @MainActor - func startRefundM(transactionId: String) async throws { + func startRefundM(transactionId: String, viewHandles: Bool = false) async throws { let request = StartRefundQueryRequest(transactionId: transactionId) - let _ = try await sendRequest(request, ASYNCDELAY) + let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } } diff --git a/TalerWallet1/Model/Model+Settings.swift b/TalerWallet1/Model/Model+Settings.swift @@ -33,13 +33,13 @@ fileprivate struct WithdrawTestBalanceRequest: WalletBackendFormattedRequest { } } extension WalletModel { - @MainActor func loadTestKudosM(test: Bool, amount: Amount) + @MainActor func loadTestKudosM(test: Bool, amount: Amount, viewHandles: Bool = false) async throws { // M for MainActor let request = WithdrawTestBalanceRequest(amount: amount, // bankBaseUrl: test ? TESTBANK : DEMOBANK, corebankApiBaseUrl: test ? TESTBANK : DEMOBANK, exchangeBaseUrl: test ? TESTEXCHANGE : DEMOEXCHANGE) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } } // loadTestKudosM() // MARK: - @@ -77,7 +77,7 @@ fileprivate struct RunIntegrationTest: WalletBackendFormattedRequest { } } extension WalletModel { - @MainActor func runIntegrationTestM(newVersion: Bool, test: Bool) + @MainActor func runIntegrationTestM(newVersion: Bool, test: Bool, viewHandles: Bool = false) async throws { // M for MainActor let amountW = Amount(currency: test ? TESTCURRENCY : DEMOCURRENCY, cent: 300) let amountS = Amount(currency: test ? TESTCURRENCY : DEMOCURRENCY, cent: 100) @@ -89,7 +89,7 @@ extension WalletModel { merchantAuthToken: MERCHANTAUTHTOKEN, amountToWithdraw: amountW, amountToSpend: amountS) - let _ = try await sendRequest(request, ASYNCDELAY) + let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } } // runIntegrationTestM() // MARK: - @@ -111,9 +111,9 @@ fileprivate struct InfiniteTransactionLoop: WalletBackendFormattedRequest { } } extension WalletModel { - func testingInfiniteTransaction(delayMs: Int32, shouldFetch: Bool) + func testingInfiniteTransaction(delayMs: Int32, shouldFetch: Bool, viewHandles: Bool = false) async throws { let request = InfiniteTransactionLoop(delayMs: delayMs, shouldFetch: shouldFetch) - let _ = try await sendRequest(request, ASYNCDELAY) + let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } } // runIntegrationTestM() diff --git a/TalerWallet1/Model/Model+Transactions.swift b/TalerWallet1/Model/Model+Transactions.swift @@ -104,47 +104,47 @@ struct ResumeTransaction: WalletBackendFormattedRequest { extension WalletModel { /// ask wallet-core for its list of transactions filtered by searchString func transactionsT(_ stack: CallStack, scopeInfo: ScopeInfo, searchString: String? = nil, - sort: String = "descending", includeRefreshes: Bool = false) + sort: String = "descending", includeRefreshes: includeRefreshes, viewHandles: Bool = false) async throws -> [Transaction] { let request = GetTransactions(scopeInfo: scopeInfo, currency: scopeInfo.currency, search: searchString, sort: sort, includeRefreshes: includeRefreshes) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response.transactions } /// fetch transactions from Wallet-Core. No networking involved - @MainActor func transactionsMA(_ stack: CallStack, scopeInfo: ScopeInfo, searchString: String? = nil, sort: String = "descending") + @MainActor func transactionsMA(_ stack: CallStack, scopeInfo: ScopeInfo, searchString: String? = nil, sort: String = "descending", viewHandles: Bool = false) async throws -> [Transaction] { // M for MainActor - return try await transactionsT(stack.push(), scopeInfo: scopeInfo, searchString: searchString, sort: sort) + return try await transactionsT(stack.push(), scopeInfo: scopeInfo, searchString: searchString, sort: sort, viewHandles: viewHandles) } /// abort the specified transaction from Wallet-Core. No networking involved - func abortTransaction(transactionId: String) async throws { + func abortTransaction(transactionId: String, viewHandles: Bool = false) async throws { let request = AbortTransaction(transactionId: transactionId) logger.notice("abortTransaction: \(transactionId, privacy: .private(mask: .hash))") - let _ = try await sendRequest(request, ASYNCDELAY) + let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } /// delete the specified transaction from Wallet-Core. No networking involved - func deleteTransaction(transactionId: String) async throws { + func deleteTransaction(transactionId: String, viewHandles: Bool = false) async throws { let request = DeleteTransaction(transactionId: transactionId) logger.notice("deleteTransaction: \(transactionId, privacy: .private(mask: .hash))") - let _ = try await sendRequest(request, ASYNCDELAY) + let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } - func failTransaction(transactionId: String) async throws { + func failTransaction(transactionId: String, viewHandles: Bool = false) async throws { let request = FailTransaction(transactionId: transactionId) logger.notice("failTransaction: \(transactionId, privacy: .private(mask: .hash))") - let _ = try await sendRequest(request, ASYNCDELAY) + let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } - func suspendTransaction(transactionId: String) async throws { + func suspendTransaction(transactionId: String, viewHandles: Bool = false) async throws { let request = SuspendTransaction(transactionId: transactionId) logger.notice("suspendTransaction: \(transactionId, privacy: .private(mask: .hash))") - let _ = try await sendRequest(request, ASYNCDELAY) + let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } - func resumeTransaction(transactionId: String) async throws { + func resumeTransaction(transactionId: String, viewHandles: Bool = false) async throws { let request = ResumeTransaction(transactionId: transactionId) logger.notice("resumeTransaction: \(transactionId, privacy: .private(mask: .hash))") - let _ = try await sendRequest(request, ASYNCDELAY) + let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } } diff --git a/TalerWallet1/Model/Model+Withdraw.swift b/TalerWallet1/Model/Model+Withdraw.swift @@ -194,57 +194,57 @@ fileprivate struct AcceptManualWithdrawal: WalletBackendFormattedRequest { extension WalletModel { /// load withdraw-exchange details. Networking involved @MainActor // M for MainActor - func loadWithdrawalExchangeForUriM(_ talerUri: String) + func loadWithdrawalExchangeForUriM(_ talerUri: String, viewHandles: Bool = false) async throws -> WithdrawExchangeResponse { let request = PrepareWithdrawExchange(talerUri: talerUri) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } /// load withdrawal details. Networking involved @MainActor // M for MainActor - func getWithdrawalDetailsForUriM(_ talerWithdrawUri: String) + func getWithdrawalDetailsForUriM(_ talerWithdrawUri: String, viewHandles: Bool = false) async throws -> WithdrawUriInfoResponse { let request = GetWithdrawalDetailsForURI(talerWithdrawUri: talerWithdrawUri) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @MainActor // M for MainActor - func getWithdrawalDetailsForAmountM(_ exchangeBaseUrl: String, amount: Amount, cancellationId: String? = nil) + func getWithdrawalDetailsForAmountM(_ exchangeBaseUrl: String, amount: Amount, cancellationId: String? = nil, viewHandles: Bool = false) async throws -> WithdrawalAmountDetails { let request = GetWithdrawalDetailsForAmount(exchangeBaseUrl: exchangeBaseUrl, amount: amount, cancellationId: cancellationId) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @MainActor // M for MainActor - func loadExchangeTermsOfServiceM(_ exchangeBaseUrl: String, acceptedFormat: [String], acceptLanguage: String) + func loadExchangeTermsOfServiceM(_ exchangeBaseUrl: String, acceptedFormat: [String], acceptLanguage: String, viewHandles: Bool = false) async throws -> ExchangeTermsOfService { let request = GetExchangeTermsOfService(exchangeBaseUrl: exchangeBaseUrl, acceptedFormat: acceptedFormat, acceptLanguage: acceptLanguage) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @MainActor // M for MainActor - func setExchangeTOSAcceptedM(_ exchangeBaseUrl: String, etag: String) + func setExchangeTOSAcceptedM(_ exchangeBaseUrl: String, etag: String, viewHandles: Bool = false) async throws -> Decodable { let request = SetExchangeTOSAccepted(exchangeBaseUrl: exchangeBaseUrl, etag: etag) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @MainActor // M for MainActor - func sendAcceptIntWithdrawalM(_ exchangeBaseUrl: String, withdrawURL: String) + func sendAcceptIntWithdrawalM(_ exchangeBaseUrl: String, withdrawURL: String, viewHandles: Bool = false) async throws -> AcceptWithdrawalResponse? { let request = AcceptBankIntegratedWithdrawal(talerWithdrawUri: withdrawURL, exchangeBaseUrl: exchangeBaseUrl) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @MainActor // M for MainActor - func sendAcceptManualWithdrawalM(_ exchangeBaseUrl: String, amount: Amount, restrictAge: Int?) + func sendAcceptManualWithdrawalM(_ exchangeBaseUrl: String, amount: Amount, restrictAge: Int?, viewHandles: Bool = false) async throws -> AcceptManualWithdrawalResult? { let request = AcceptManualWithdrawal(exchangeBaseUrl: exchangeBaseUrl, amount: amount, restrictAge: restrictAge) - let response = try await sendRequest(request, ASYNCDELAY) + let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } } diff --git a/TalerWallet1/Model/WalletModel.swift b/TalerWallet1/Model/WalletModel.swift @@ -32,7 +32,7 @@ class WalletModel: ObservableObject { didSet { showError = error != nil } } - func sendRequest<T: WalletBackendFormattedRequest> (_ request: T, _ delay: UInt = 0) + func sendRequest<T: WalletBackendFormattedRequest> (_ request: T, _ delay: UInt = 0, viewHandles: Bool = false) async throws -> T.Response { // T for any Thread #if !DEBUG logger.log("sending: \(request.operation(), privacy: .public)") @@ -52,20 +52,24 @@ class WalletModel: ObservableObject { } catch { // rethrows let timeUsed = Date.now - sendTime logger.error("\(request.operation(), privacy: .public) failed after \(timeUsed.milliseconds, privacy: .public) ms\n\(error, privacy: .public)") + if !viewHandles { + // TODO: symlog + controller sound + self.error = .error(error) + } throw error } } - func getTransactionByIdT(_ transactionId: String) + func getTransactionByIdT(_ transactionId: String, viewHandles: Bool = false) async throws -> Transaction { // T for any Thread // might be called from a background thread itself let request = GetTransactionById(transactionId: transactionId) - return try await sendRequest(request, ASYNCDELAY) + return try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) } /// get the specified transaction from Wallet-Core. No networking involved - @MainActor func getTransactionByIdM(_ transactionId: String) + @MainActor func getTransactionByIdM(_ transactionId: String, viewHandles: Bool = false) async throws -> Transaction { // M for MainActor - return try await getTransactionByIdT(transactionId) // call GetTransactionById on main thread + return try await getTransactionByIdT(transactionId, viewHandles: viewHandles) // call GetTransactionById on main thread } } // MARK: - @@ -182,11 +186,11 @@ fileprivate struct InitRequest: WalletBackendFormattedRequest { extension WalletModel { /// initalize Wallet-Core. Will do networking - func initWalletCoreT(setTesting: Bool) async throws -> VersionInfo { + func initWalletCoreT(setTesting: Bool, viewHandles: Bool = false) async throws -> VersionInfo { // T for any Thread let docPath = try docPath(sqlite3: true) let request = InitRequest(persistentStoragePath: docPath, setTesting: setTesting) - let response = try await sendRequest(request, 0) // no Delay + let response = try await sendRequest(request, 0, viewHandles: viewHandles) // no Delay return response.versionInfo } @@ -238,10 +242,10 @@ fileprivate struct ResetRequest: WalletBackendFormattedRequest { extension WalletModel { /// reset Wallet-Core - func resetWalletCoreT() async throws { + func resetWalletCoreT(viewHandles: Bool = false) async throws { // T for any Thread let request = ResetRequest() - _ = try await sendRequest(request, 0) + _ = try await sendRequest(request, 0, viewHandles: viewHandles) } } // MARK: - @@ -260,10 +264,10 @@ fileprivate struct DevExperimentRequest: WalletBackendFormattedRequest { extension WalletModel { /// tell wallet-core to mock new transactions - func devExperimentT(talerUri: String) async throws { + func devExperimentT(talerUri: String, viewHandles: Bool = false) async throws { // T for any Thread let request = DevExperimentRequest(talerUri: talerUri) - _ = try await sendRequest(request, 0) + _ = try await sendRequest(request, 0, viewHandles: viewHandles) } } diff --git a/TalerWallet1/Views/Balances/BalancesListView.swift b/TalerWallet1/Views/Balances/BalancesListView.swift @@ -84,15 +84,10 @@ struct BalancesListView: View { model.cachedBalances = nil } - do { - let reloaded = try await model.balancesM(stack.push()) + if let reloaded = try? await model.balancesM(stack.push()) { let count = reloaded.count balances = reloaded // redraw return count - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) } return nil diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift b/TalerWallet1/Views/Balances/BalancesSectionView.swift @@ -40,32 +40,22 @@ struct BalancesSectionView { @State private var completedTransactions: [Transaction] = [] @State private var pendingTransactions: [Transaction] = [] - func reloadOneAction(_ transactionId: String) async throws -> Transaction { - return try await model.getTransactionByIdT(transactionId) + func reloadOneAction(_ transactionId: String, _ viewHandles: Bool) async throws -> Transaction { + return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) } @State private var sectionID = UUID() @State private var shownSectionID = UUID() // guaranteed to be different the first time func reloadCompleted(_ stack: CallStack) async -> () { - do { - transactions = try await model.transactionsT(stack.push(), scopeInfo: balance.scopeInfo, includeRefreshes: developerMode) + if let transactions = try? await model.transactionsT(stack.push(), scopeInfo: balance.scopeInfo, includeRefreshes: developerMode) { completedTransactions = WalletModel.completedTransactions(transactions) - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) } } func reloadPending(_ stack: CallStack) async -> () { - do { - transactions = try await model.transactionsT(stack.push(), scopeInfo: balance.scopeInfo, includeRefreshes: developerMode) + if let transactions = try? await model.transactionsT(stack.push(), scopeInfo: balance.scopeInfo, includeRefreshes: developerMode) { pendingTransactions = WalletModel.pendingTransactions(transactions) - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) } } } @@ -140,16 +130,11 @@ extension BalancesSectionView: View { // if shownSectionID != sectionID { symLog.log(".task for BalancesSectionView - reload Transactions") // TODO: only load the MAXRECENT most recent transactions - do { - let response = try await model.transactionsT(stack.push(".task - reload Transactions"), scopeInfo: scopeInfo, includeRefreshes: developerMode) + if let response = try? await model.transactionsT(stack.push(".task - reload Transactions"), scopeInfo: scopeInfo, includeRefreshes: developerMode) { transactions = response pendingTransactions = WalletModel.pendingTransactions(response) completedTransactions = WalletModel.completedTransactions(response) shownSectionID = sectionID - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) } // } else { // symLog.log("task for BalancesSectionView \(sectionID) ❗️ skip reloading Transactions") @@ -187,7 +172,7 @@ fileprivate struct BalancesPendingRowView: View { let balance: Balance // this is the currency to be used @Binding var pendingTransactions: [Transaction] let reloadPending: (_ stack: CallStack) async -> () - let reloadOneAction: ((_ transactionId: String) async throws -> Transaction) + let reloadOneAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Transaction) var body: some View { let pendingIncoming = balance.pendingIncoming @@ -247,7 +232,7 @@ fileprivate struct BalancesNavigationLinksView: View { @Binding var summary: String @Binding var completedTransactions: [Transaction] let reloadAllAction: (_ stack: CallStack) async -> () - let reloadOneAction: ((_ transactionId: String) async throws -> Transaction) + let reloadOneAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Transaction) // @EnvironmentObject private var model: WalletModel @State private var buttonSelected: Int? = nil diff --git a/TalerWallet1/Views/Banking/DepositAmountV.swift b/TalerWallet1/Views/Banking/DepositAmountV.swift @@ -122,13 +122,11 @@ struct DepositAmountV: View { depositStarted = true // don't run twice Task { // runs on MainActor symLog.log("Deposit") - do { - let result = try await model.createDepositGroupM(paytoUri, amount: amountToTransfer) + if let result = try? await model.createDepositGroupM(paytoUri, amount: amountToTransfer) { symLog.log(result.transactionId) ViewState2.shared.popToRootView(stack.push()) NotificationCenter.default.post(name: .TransactionDone, object: nil, userInfo: nil) - } catch { // TODO: show error - symLog.log(error.localizedDescription) + } else { depositStarted = false } } @@ -168,15 +166,13 @@ struct DepositAmountV: View { feeStr = EMPTYSTRING prepareDepositResult = nil } else if let paytoUri { - do { - let ppCheck = try await model.prepareDepositM(paytoUri, amount: amountToTransfer) + if let ppCheck = try? await model.prepareDepositM(paytoUri, amount: amountToTransfer) { prepareDepositResult = ppCheck if let feeAmount = fee(ppCheck: prepareDepositResult) { feeStr = feeAmount.string(currencyInfo) } else { feeStr = EMPTYSTRING } announce(this: "\(amountVoiceOver), \(feeLabel)") - } catch { // TODO: error - symLog.log(error.localizedDescription) + } else { prepareDepositResult = nil } } diff --git a/TalerWallet1/Views/Banking/DepositIbanV.swift b/TalerWallet1/Views/Banking/DepositIbanV.swift @@ -127,13 +127,10 @@ struct DepositIbanV: View { // print("❗️ P2PSubjectV onDisappear") } .task(id: depositIBAN) { - do { - if try await model.validateIbanM(depositIBAN) { - let payto = "payto://iban/\(depositIBAN)?receiver-name=\(accountHolder)" - paytoUri = payto.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! - } - } catch { // TODO: error - symLog.log(error.localizedDescription) + if (try? await model.validateIbanM(depositIBAN)) == true { + let payto = "payto://iban/\(depositIBAN)?receiver-name=\(accountHolder)" + paytoUri = payto.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! + } else { paytoUri = nil } } diff --git a/TalerWallet1/Views/Banking/ExchangeListView.swift b/TalerWallet1/Views/Banking/ExchangeListView.swift @@ -24,14 +24,9 @@ struct ExchangeListView: View { func addExchange(_ exchange: String) -> Void { Task { // runs on MainActor symLog.log("adding: \(exchange)") - do { - try await model.addExchange(url: exchange) + if let _ = try? await model.addExchange(url: exchange) { symLog.log("added: \(exchange)") announce(this: "added: \(exchange)") - } catch { - symLog.log("error: \(error)") - model.showError(.error(error)) - controller.playSound(0) } } } @@ -88,11 +83,8 @@ struct ExchangeListCommonV { @State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING) // TODO: Hold different values for different currencies? func reloadExchanges() async -> Void { - do { - exchanges = try await model.listExchangesM() - } catch { - model.showError(.error(error)) - controller.playSound(0) + if let exc = try? await model.listExchangesM() { + exchanges = exc } } } diff --git a/TalerWallet1/Views/Banking/ExchangeRowView.swift b/TalerWallet1/Views/Banking/ExchangeRowView.swift @@ -64,12 +64,9 @@ struct ExchangeRowView: View { // FIXME: remove fake ScopeInfo once the REAL one is in exchange.scopeInfo let scopeInfo = exchange.scopeInfo ?? ScopeInfo(type: .global, currency: currency) - do { - let info = try await model.getCurrencyInfoM(scope: scopeInfo, delay: delay) + if let info = try? await model.getCurrencyInfoM(scope: scopeInfo, delay: delay) { // logger.info("got info: \(scope.currency, privacy: .public)") await controller.setInfo(info) - } catch { // TODO: error handling - couldn't get CurrencyInfo -// logger.error("Couldn't get info for: \(scope.currency, privacy: .public)\n\(error)") } } } diff --git a/TalerWallet1/Views/Banking/ManualWithdrawDone.swift b/TalerWallet1/Views/Banking/ManualWithdrawDone.swift @@ -20,8 +20,8 @@ struct ManualWithdrawDone: View { @State private var acceptManualWithdrawalResult: AcceptManualWithdrawalResult? @State private var transactionId: String? - func reloadOneAction(_ transactionId: String) async throws -> Transaction { - return try await model.getTransactionByIdT(transactionId) + func reloadOneAction(_ transactionId: String, viewHandles: Bool) async throws -> Transaction { + return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) } func dismissTopAnimated(_ stack: CallStack) { dismissTop() @@ -55,12 +55,9 @@ struct ManualWithdrawDone: View { DebugViewC.shared.setViewID(VIEW_WITHDRAW_ACCEPT, stack: stack.push()) }.task { if transactionId == nil { - do { - let result = try await model.sendAcceptManualWithdrawalM(exchange.exchangeBaseUrl, - amount: amountToTransfer, restrictAge: 0) - transactionId = result!.transactionId - } catch { // TODO: error - symLog.log(error.localizedDescription) + if let result = try? await model.sendAcceptManualWithdrawalM(exchange.exchangeBaseUrl, + amount: amountToTransfer, restrictAge: 0) { + transactionId = result.transactionId } } } diff --git a/TalerWallet1/Views/HelperViews/AmountInputV.swift b/TalerWallet1/Views/HelperViews/AmountInputV.swift @@ -33,8 +33,7 @@ struct AmountInputV: View { func preparePayForTemplate() async { if let url { - do { - let ppCheck = try await model.preparePayForTemplateM(url.absoluteString, amount: amountToTransfer, summary: summary) + if let ppCheck = try? await model.preparePayForTemplateM(url.absoluteString, amount: amountToTransfer, summary: summary) { let amount = ppCheck.amountRaw let currency = amount.currencyStr let currencyInfo = controller.info(for: currency, controller.currencyTicker) @@ -46,8 +45,6 @@ struct AmountInputV: View { let amountVoiceOver = amount.string(currencyInfo) announce(this: "\(amountVoiceOver), \(feeLabel)") preparePayResult = ppCheck - } catch { // TODO: error - symLog.log(error.localizedDescription) } } } diff --git a/TalerWallet1/Views/HelperViews/BarGraph.swift b/TalerWallet1/Views/HelperViews/BarGraph.swift @@ -38,14 +38,9 @@ struct BarGraphHeader: View { if let scopeInfo { symLog.log(".task for BarGraphHeader(\(scopeInfo.currency)) - reload Transactions") // TODO: only load the 10 most recent transactions - do { - let response = try await model.transactionsT(stack.push(".task - reload Transactions for \(scopeInfo.currency)"), - scopeInfo: scopeInfo) + if let response = try? await model.transactionsT(stack.push(".task - reload Transactions for \(scopeInfo.currency)"), + scopeInfo: scopeInfo) { completedTransactions = WalletModel.completedTransactions(response) - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) } } } diff --git a/TalerWallet1/Views/HelperViews/SubjectInputV.swift b/TalerWallet1/Views/HelperViews/SubjectInputV.swift @@ -38,8 +38,7 @@ struct SubjectInputV<TargetView: View>: View { func preparePayForTemplate() async { if let url { - do { - let ppCheck = try await model.preparePayForTemplateM(url.absoluteString, amount: amountToTransfer, summary: summary) + if let ppCheck = try? await model.preparePayForTemplateM(url.absoluteString, amount: amountToTransfer, summary: summary) { let amount = ppCheck.amountRaw let currency = amount.currencyStr let currencyInfo = controller.info(for: currency, controller.currencyTicker) @@ -51,8 +50,6 @@ struct SubjectInputV<TargetView: View>: View { let amountVoiceOver = amount.string(currencyInfo) announce(this: "\(amountVoiceOver), \(feeLabel)") preparePayResult = ppCheck - } catch { // TODO: error - symLog.log(error.localizedDescription) } } } diff --git a/TalerWallet1/Views/HelperViews/TransactionButton.swift b/TalerWallet1/Views/HelperViews/TransactionButton.swift @@ -10,7 +10,7 @@ struct TransactionButton: View { let transactionId: String let command: TxAction let warning: String? - let action: (_ transactionId: String) async throws -> Void + let action: (_ transactionId: String, _ viewHandles: Bool) async throws -> Void @AppStorage("shouldShowWarning") var shouldShowWarning: Bool = true @@ -21,12 +21,9 @@ struct TransactionButton: View { private func doAction() { disabled = true // don't try this more than once Task { // runs on MainActor - do { - try await action(transactionId) + if let _ = try? await action(transactionId, false) { // symLog.log("\(executed) \(transactionId)") executed = true - } catch { // TODO: error -// symLog.log(error.localizedDescription) } } } @@ -75,7 +72,7 @@ struct TransactionButton: View { #if DEBUG struct TransactionButton_Previews: PreviewProvider { - static func action(_ transactionId: String) async throws { + static func action(_ transactionId: String, _ viewHandles: Bool) async throws { print(transactionId) } diff --git a/TalerWallet1/Views/Main/MainView.swift b/TalerWallet1/Views/Main/MainView.swift @@ -271,13 +271,8 @@ extension MainView { let scope = balance.scopeInfo if controller.hasInfo(for: scope.currency) == nil { Task { // runs on MainActor - do { - let info = try await model.getCurrencyInfoM(scope: scope, delay: delay) + if let info = try? await model.getCurrencyInfoM(scope: scope, delay: delay) { await controller.setInfo(info) - } catch { // TODO: error handling - couldn't get CurrencyInfo - logger.error("Couldn't get info for: \(scope.currency, privacy: .public)\n\(error)") - model.showError(.error(error)) - controller.playSound(0) } } } diff --git a/TalerWallet1/Views/Main/WalletEmptyView.swift b/TalerWallet1/Views/Main/WalletEmptyView.swift @@ -44,11 +44,7 @@ struct WalletEmptyView: View { Task { // runs on MainActor let amount = Amount(currency: DEMOCURRENCY, cent: 2500) symLog.log("Withdraw KUDOS") - do { - try await model.loadTestKudosM(test: false, amount: amount) - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + try? await model.loadTestKudosM(test: false, amount: amount) } } .buttonStyle(TalerButtonStyle(type: .prominent, narrow: false, disabled: withDrawDisabled, aligned: .center)) diff --git a/TalerWallet1/Views/Peer2peer/P2PReadyV.swift b/TalerWallet1/Views/Peer2peer/P2PReadyV.swift @@ -27,8 +27,8 @@ struct P2PReadyV: View { let navTitle = String(localized: "P2P Ready") @State private var transactionId: String? = nil - func reloadOneAction(_ transactionId: String) async throws -> Transaction { - return try await model.getTransactionByIdT(transactionId) + func reloadOneAction(_ transactionId: String, viewHandles: Bool) async throws -> Transaction { + return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) } var body: some View { @@ -69,35 +69,33 @@ struct P2PReadyV: View { } .task(id: amountToTransfer.value) { symLog.log(".task") - do { - guard transactionStarted == false else { + guard transactionStarted == false else { // TODO: logger.warning("Try to start P2P a second time") - symLog.log("Yikes❗️ Try to start P2P a second time") - return - } - transactionStarted = true - let timestamp = developerMode ? Timestamp.inSomeMinutes(expireDays > 20 ? (24*60) - : expireDays > 5 ? 60 : 3) - : Timestamp.inSomeDays(expireDays) - if amountToSend { - let terms = PeerContractTerms(amount: amountToTransfer, - summary: summary, - purse_expiration: timestamp) - // TODO: let user choose baseURL - let response = try await model.initiatePeerPushDebitM(nil, terms: terms) + symLog.log("Yikes❗️ Try to start P2P a second time") + return + } + transactionStarted = true + let timestamp = developerMode ? Timestamp.inSomeMinutes(expireDays > 20 ? (24*60) + : expireDays > 5 ? 60 : 3) + : Timestamp.inSomeDays(expireDays) + if amountToSend { + let terms = PeerContractTerms(amount: amountToTransfer, + summary: summary, + purse_expiration: timestamp) + // TODO: let user choose baseURL + if let response = try? await model.initiatePeerPushDebitM(nil, terms: terms) { // will switch from WithdrawProgressView to TransactionSummaryV transactionId = response.transactionId - } else { - let terms = PeerContractTerms(amount: amountToTransfer, - summary: summary, - purse_expiration: timestamp) - // TODO: let user choose baseURL - let response = try await model.initiatePeerPullCreditM(nil, terms: terms) + } + } else { + let terms = PeerContractTerms(amount: amountToTransfer, + summary: summary, + purse_expiration: timestamp) + // TODO: let user choose baseURL + if let response = try? await model.initiatePeerPullCreditM(nil, terms: terms) { // will switch from WithdrawProgressView to TransactionSummaryV transactionId = response.transactionId } - } catch { // TODO: error - symLog.log(error.localizedDescription) } } // task } diff --git a/TalerWallet1/Views/Peer2peer/P2PSubjectV.swift b/TalerWallet1/Views/Peer2peer/P2PSubjectV.swift @@ -134,14 +134,11 @@ struct P2PSubjectV: View { } .task(id: amountToTransfer.value) { if amountToSend && feeLabel == nil { - do { - let ppCheck = try await model.checkPeerPushDebitM(amountToTransfer) + if let ppCheck = try? await model.checkPeerPushDebitM(amountToTransfer) { if let feeAmount = p2pFee(ppCheck: ppCheck) { let feeStr = feeAmount.string(currencyInfo) myFeeLabel = String(localized: "+ \(feeStr) fee") } else { myFeeLabel = EMPTYSTRING } - } catch { // TODO: error - symLog.log(error.localizedDescription) } } } diff --git a/TalerWallet1/Views/Peer2peer/RequestPayment.swift b/TalerWallet1/Views/Peer2peer/RequestPayment.swift @@ -105,27 +105,13 @@ struct RequestPayment: View { .task(id: amountToTransfer.value) { if exchange == nil { if let url = scopeInfo.url { - do { - exchange = try await model.getExchangeByUrl(url: url) - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) - } + exchange = try? await model.getExchangeByUrl(url: url) } } if amountToTransfer.isZero { // fee = EMPTYSTRING } else { - do { - let ppCheck = try await model.checkPeerPullCreditM(amountToTransfer, exchangeBaseUrl: nil) - peerPullCheck = ppCheck // redraw - // TODO: set from exchange -// agePicker.setAges(ages: peerPushCheck?.ageRestrictionOptions) - } catch { // TODO: error - symLog.log(error.localizedDescription) - peerPullCheck = nil - } + peerPullCheck = try? await model.checkPeerPullCreditM(amountToTransfer, exchangeBaseUrl: nil) } } } diff --git a/TalerWallet1/Views/Peer2peer/SendAmount.swift b/TalerWallet1/Views/Peer2peer/SendAmount.swift @@ -133,13 +133,7 @@ struct SendAmount: View { .task(id: amountToTransfer.value) { if exchange == nil { if let url = scopeInfo.url { - do { - exchange = try await model.getExchangeByUrl(url: url) - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) - } + exchange = try? await model.getExchangeByUrl(url: url) } } do { @@ -154,8 +148,7 @@ struct SendAmount: View { } else if amountToTransfer.isZero { feeStr = EMPTYSTRING } else { - do { - let ppCheck = try await model.checkPeerPushDebitM(amountToTransfer) + if let ppCheck = try? await model.checkPeerPushDebitM(amountToTransfer) { peerPushCheck = ppCheck // TODO: set from exchange // agePicker.setAges(ages: peerPushCheck?.ageRestrictionOptions) @@ -163,8 +156,7 @@ struct SendAmount: View { feeStr = feeAmount.string(currencyInfo) } else { feeStr = EMPTYSTRING } announce(this: "\(amountVoiceOver), \(feeLabel)") - } catch { // TODO: error - symLog.log(error.localizedDescription) + } else { peerPushCheck = nil } } diff --git a/TalerWallet1/Views/Settings/SettingsView.swift b/TalerWallet1/Views/Settings/SettingsView.swift @@ -65,11 +65,7 @@ struct SettingsView: View { showResetAlert = false Task { // runs on MainActor symLog.log("❗️Reset wallet-core❗️") - do { - try await model.resetWalletCoreT() - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + try? await model.resetWalletCoreT() } } } @@ -186,12 +182,8 @@ struct SettingsView: View { withDrawDisabled = true // don't run twice Task { // runs on MainActor symLog.log("Withdraw KUDOS") - do { - let amount = Amount(currency: DEMOCURRENCY, cent: 1100) - try await model.loadTestKudosM(test: false, amount: amount) - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + let amount = Amount(currency: DEMOCURRENCY, cent: 1100) + try? await model.loadTestKudosM(test: false, amount: amount) } } .buttonStyle(.bordered) @@ -204,12 +196,8 @@ struct SettingsView: View { withDrawDisabled = true // don't run twice Task { // runs on MainActor symLog.log("Withdraw TESTKUDOS") - do { - let amount = Amount(currency: TESTCURRENCY, cent: 1100) - try await model.loadTestKudosM(test: true, amount: amount) - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + let amount = Amount(currency: TESTCURRENCY, cent: 1100) + try? await model.loadTestKudosM(test: true, amount: amount) } } .buttonStyle(.bordered) @@ -227,13 +215,9 @@ struct SettingsView: View { Button(title) { Task { // runs on MainActor symLog.log("running applyDevExperiment Refresh") - do { - try await model.setConfigT(setTesting: true) - try await model.devExperimentT(talerUri: "taler://dev-experiment/start-block-refresh") - try await model.devExperimentT(talerUri: "taler://dev-experiment/insert-pending-refresh") - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + try? await model.setConfigT(setTesting: true) + try? await model.devExperimentT(talerUri: "taler://dev-experiment/start-block-refresh") + try? await model.devExperimentT(talerUri: "taler://dev-experiment/insert-pending-refresh") } } .buttonStyle(.bordered) @@ -246,11 +230,7 @@ struct SettingsView: View { checkDisabled = true // don't run twice Task { // runs on MainActor symLog.log("running integration test on demo") - do { - try await model.runIntegrationTestM(newVersion: false, test: false) - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + try? await model.runIntegrationTestM(newVersion: false, test: false) } } .buttonStyle(.bordered) @@ -263,11 +243,7 @@ struct SettingsView: View { checkDisabled = true // don't run twice Task { // runs on MainActor symLog.log("running integration test on test") - do { - try await model.runIntegrationTestM(newVersion: false, test: true) - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + try? await model.runIntegrationTestM(newVersion: false, test: true) } } .buttonStyle(.bordered) @@ -280,11 +256,7 @@ struct SettingsView: View { checkDisabled = true // don't run twice Task { // runs on MainActor symLog.log("running integration test V2 on demo") - do { - try await model.runIntegrationTestM(newVersion: true, test: false) - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + try? await model.runIntegrationTestM(newVersion: true, test: false) } } .buttonStyle(.bordered) @@ -297,11 +269,7 @@ struct SettingsView: View { checkDisabled = true // don't run twice Task { // runs on MainActor symLog.log("running integration test V2 on test") - do { - try await model.runIntegrationTestM(newVersion: true, test: true) - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + try? await model.runIntegrationTestM(newVersion: true, test: true) } } .buttonStyle(.bordered) @@ -314,11 +282,7 @@ struct SettingsView: View { checkDisabled = true // don't run twice Task { // runs on MainActor symLog.log("Running Infinite Transaction Loop") - do { - try await model.testingInfiniteTransaction(delayMs: 10_000, shouldFetch: true) - } catch { // TODO: show error - symLog.log(error.localizedDescription) - } + try? await model.testingInfiniteTransaction(delayMs: 10_000, shouldFetch: true) } } .buttonStyle(.bordered) diff --git a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift @@ -34,16 +34,14 @@ struct P2pAcceptDone: View { : SHEET_PAY_P2P_ACCEPT) } .task { - do { - if incoming { - _ = try await model.acceptPeerPushCreditM(transactionId) - } else { - _ = try await model.confirmPeerPullDebitM(transactionId) + if incoming { + if let _ = try? await model.acceptPeerPushCreditM(transactionId) { + dismissTop() + } + } else { + if let _ = try? await model.confirmPeerPullDebitM(transactionId) { + dismissTop() } - dismissTop() - } catch { // TODO: error - symLog.log(error.localizedDescription) - controller.playSound(0) } } } diff --git a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pPayURIView.swift b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pPayURIView.swift @@ -73,11 +73,7 @@ struct P2pPayURIView: View { LoadingView(scopeInfo: nil, message: message) .task { do { symLog.log(".task") - let ppDebitResponse = try await model.preparePeerPullDebitM(url.absoluteString) - peerPullDebitResponse = ppDebitResponse - } catch { // TODO: error - symLog.log(error.localizedDescription) - peerPullDebitResponse = nil + peerPullDebitResponse = try? await model.preparePeerPullDebitM(url.absoluteString) } } } } diff --git a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift @@ -88,15 +88,11 @@ struct P2pReceiveURIView: View { DebugViewC.shared.setSheetID(SHEET_RCV_P2P) } .task { // must be here and not at LoadingView(), because this needs to run a 2nd time after ToS was accepted - do { // TODO: cancelled - symLog.log(".task") - let ppResponse = try await model.preparePeerPushCreditM(url.absoluteString) - exchange = try await model.getExchangeByUrl(url: ppResponse.exchangeBaseUrl) + symLog.log(".task") + if let ppResponse = try? await model.preparePeerPushCreditM(url.absoluteString) { + exchange = try? await model.getExchangeByUrl(url: ppResponse.exchangeBaseUrl) peerPushCreditResponse = ppResponse - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) + } else { peerPushCreditResponse = nil } } diff --git a/TalerWallet1/Views/Sheets/Payment/PayTemplateV.swift b/TalerWallet1/Views/Sheets/Payment/PayTemplateV.swift @@ -62,17 +62,12 @@ struct PayTemplateV: View { } func acceptAction(preparePayResult: PreparePayResult) { Task { // runs on MainActor - do { - let confirmPayResult = try await model.confirmPayM(preparePayResult.transactionId) -// symLog.log(confirmPayResult as Any) + if let confirmPayResult = try? await model.confirmPayM(preparePayResult.transactionId) { + // symLog.log(confirmPayResult as Any) if confirmPayResult.type != "done" { controller.playSound(0) // TODO: show error } - } catch { - controller.playSound(0) - // TODO: error - symLog.log(error.localizedDescription) } dismissTop() } @@ -94,8 +89,7 @@ struct PayTemplateV: View { } func preparePayForTemplate() async { - do { - let ppCheck = try await model.preparePayForTemplateM(url.absoluteString, amount: amountToTransfer, summary: summary) + if let ppCheck = try? await model.preparePayForTemplateM(url.absoluteString, amount: amountToTransfer, summary: summary) { let amount = ppCheck.amountRaw let currency = amount.currencyStr let currencyInfo = controller.info(for: currency, controller.currencyTicker) @@ -107,10 +101,6 @@ struct PayTemplateV: View { let amountVoiceOver = amount.string(currencyInfo) announce(this: "\(amountVoiceOver), \(feeLabel)") preparePayResult = ppCheck - } catch { // TODO: error - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) } } diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentDone.swift b/TalerWallet1/Views/Sheets/Payment/PaymentDone.swift @@ -15,8 +15,8 @@ struct PaymentDone: View { @State var paymentDone: Bool = false - func reloadOneAction(_ transactionId: String) async throws -> Transaction { - return try await model.getTransactionByIdT(transactionId) + func reloadOneAction(_ transactionId: String, viewHandles: Bool) async throws -> Transaction { + return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) } func dismissTopAnimated(_ stack: CallStack) { dismissTop() @@ -46,9 +46,8 @@ struct PaymentDone: View { } else { LoadingView(scopeInfo: nil, message: "Paying...") .task { - do { - let confirmPayResult = try await model.confirmPayM(transactionId) -// symLog.log(confirmPayResult as Any) + if let confirmPayResult = try? await model.confirmPayM(transactionId) { + // symLog.log(confirmPayResult as Any) if confirmPayResult.type == "done" { paymentDone = true } else { @@ -56,11 +55,6 @@ struct PaymentDone: View { // TODO: show error dismissTop() } - } catch { - controller.playSound(0) - // TODO: error - symLog.log(error.localizedDescription) - dismissTop() } } } diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentView.swift b/TalerWallet1/Views/Sheets/Payment/PaymentView.swift @@ -95,21 +95,17 @@ struct PaymentView: View { } else { LoadingView(scopeInfo: nil, message: url.host) .task { // this runs only once - do { // TODO: cancelled - symLog.log(".task") - if template { - let result = try await model.preparePayForTemplateM(url.absoluteString, - amount: amountToTransfer, - summary: summary) + symLog.log(".task") + if template { + if let result = try? await model.preparePayForTemplateM(url.absoluteString, + amount: amountToTransfer, + summary: summary) { preparePayResult = result - } else { - let result = try await model.preparePayForUriM(url.absoluteString) + } + } else { + if let result = try? await model.preparePayForUriM(url.absoluteString) { preparePayResult = result } - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) } } } diff --git a/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift b/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift @@ -17,8 +17,8 @@ struct RefundURIView: View { @State var refundTransactionId: String? = nil - func reloadOneAction(_ transactionId: String) async throws -> Transaction { - return try await model.getTransactionByIdT(transactionId) + func reloadOneAction(_ transactionId: String, viewHandles: Bool) async throws -> Transaction { + return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) } var body: some View { @@ -36,12 +36,9 @@ struct RefundURIView: View { } else { LoadingView(scopeInfo: nil, message: url.host) .task { - do { - symLog.log(".task") - let result = try await model.startRefundForUriM(url: url.absoluteString) + symLog.log(".task") + if let result = try? await model.startRefundForUriM(url: url.absoluteString) { refundTransactionId = result - } catch { // TODO: error - symLog.log(error.localizedDescription) } } } diff --git a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift @@ -19,8 +19,8 @@ struct WithdrawAcceptDone: View { @State private var transactionId: String? = nil - func reloadOneAction(_ transactionId: String) async throws -> Transaction { - return try await model.getTransactionByIdT(transactionId) + func reloadOneAction(_ transactionId: String, viewHandles: Bool) async throws -> Transaction { + return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) } func dismissTopAnimated(_ stack: CallStack) { dismissTop() @@ -54,16 +54,12 @@ struct WithdrawAcceptDone: View { symLog.log("onAppear") DebugViewC.shared.setSheetID(SHEET_WITHDRAW_CONFIRM) }.task { - do { - if let exchangeBaseUrl { - let result = try await model.sendAcceptIntWithdrawalM(exchangeBaseUrl, withdrawURL: url.absoluteString) - let confirmTransferUrl = result!.confirmTransferUrl + if let exchangeBaseUrl { + if let result = try? await model.sendAcceptIntWithdrawalM(exchangeBaseUrl, withdrawURL: url.absoluteString) { + let confirmTransferUrl = result.confirmTransferUrl symLog.log(confirmTransferUrl) - transactionId = result!.transactionId + transactionId = result.transactionId } - } catch { // TODO: error - symLog.log(error.localizedDescription) - controller.playSound(0) } } } diff --git a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawTOSView.swift b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawTOSView.swift @@ -23,21 +23,15 @@ struct WithdrawTOSView: View { @State var exchangeTOS: ExchangeTermsOfService? func loadToS(_ language: String) async { - do { - if let exchangeBaseUrl { - let acceptedFormat: [String] = [MARKDOWN, PLAINTEXT] // MARKDOWN, HTML, PLAINTEXT - let someTOS = try await model.loadExchangeTermsOfServiceM(exchangeBaseUrl, - acceptedFormat: acceptedFormat, - acceptLanguage: language) + if let exchangeBaseUrl { + let acceptedFormat: [String] = [MARKDOWN, PLAINTEXT] // MARKDOWN, HTML, PLAINTEXT + if let someTOS = try? await model.loadExchangeTermsOfServiceM(exchangeBaseUrl, + acceptedFormat: acceptedFormat, + acceptLanguage: language) { exchangeTOS = someTOS - } else { - // TODO: Yikes! No baseURL - - - } - } catch { // TODO: error - symLog.log(error.localizedDescription) + } else { + // TODO: Yikes! No baseURL } } @@ -48,19 +42,15 @@ struct WithdrawTOSView: View { Content(symLog: symLog, tos: exchangeTOS, myListStyle: $myListStyle, language: languageCode, languageAction: loadToS) { Task { // runs on MainActor - do { - if let exchangeBaseUrl { - _ = try await model.setExchangeTOSAcceptedM(exchangeBaseUrl, etag: exchangeTOS.currentEtag) - if acceptAction != nil { - acceptAction!() - } else { // just go back - caller will reload - self.presentationMode.wrappedValue.dismiss() - } - } else { - // TODO: error + if let exchangeBaseUrl { + _ = try? await model.setExchangeTOSAcceptedM(exchangeBaseUrl, etag: exchangeTOS.currentEtag) + if acceptAction != nil { + acceptAction!() + } else { // just go back - caller will reload + self.presentationMode.wrappedValue.dismiss() } - } catch { // TODO: Show Error - symLog.log(error.localizedDescription) + } else { + // TODO: error } } } diff --git a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift @@ -92,26 +92,21 @@ struct WithdrawURIView: View { DebugViewC.shared.setSheetID(SHEET_WITHDRAWAL) } .task { - do { // TODO: cancelled - symLog.log(".task") - let withdrawUriInfo = try await model.getWithdrawalDetailsForUriM(url.absoluteString) + symLog.log(".task") + if let withdrawUriInfo = try? await model.getWithdrawalDetailsForUriM(url.absoluteString) { let amount = withdrawUriInfo.amount let baseUrl = withdrawUriInfo.defaultExchangeBaseUrl ?? withdrawUriInfo.possibleExchanges.first?.exchangeBaseUrl if let baseUrl { - exchange = try await model.getExchangeByUrl(url: baseUrl) - let details = try await model.getWithdrawalDetailsForAmountM(baseUrl, amount: amount) - withdrawalAmountDetails = details -// agePicker.setAges(ages: details?.ageRestrictionOptions) + exchange = try? await model.getExchangeByUrl(url: baseUrl) + if let details = try? await model.getWithdrawalDetailsForAmountM(baseUrl, amount: amount) { + withdrawalAmountDetails = details + } + // agePicker.setAges(ages: details?.ageRestrictionOptions) } else { // TODO: error symLog.log("no exchangeBaseUrl or no exchange") withdrawalAmountDetails = nil } - } catch { - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) - withdrawalAmountDetails = nil } } } diff --git a/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift b/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift @@ -40,28 +40,26 @@ struct WithdrawExchangeV: View { } .task { if exchange == nil { - do { // TODO: cancelled - symLog.log(".task") - let withdrawExchange = try await model.loadWithdrawalExchangeForUriM(url.absoluteString) + symLog.log(".task") + if let withdrawExchange = try? await model.loadWithdrawalExchangeForUriM(url.absoluteString) { let baseUrl = withdrawExchange.exchangeBaseUrl symLog.log("getExchangeByUrl(\(baseUrl))") - let exc = try await model.getExchangeByUrl(url: baseUrl) - // let the controller collect CurrencyInfo from this formerly unknown exchange - let _ = try await controller.getInfo(from: baseUrl, model: model) - if let amount = withdrawExchange.amount { - amountToTransfer = amount + if let exc = try? await model.getExchangeByUrl(url: baseUrl) { + // let the controller collect CurrencyInfo from this formerly unknown exchange + let _ = try? await controller.getInfo(from: baseUrl, model: model) + if let amount = withdrawExchange.amount { + amountToTransfer = amount + } else { + let currency = exc.scopeInfo?.currency + ?? exc.currency + ?? String(localized: "Unknown", comment: "unknown currency") + amountToTransfer.setCurrency(currency) + // is already Amount.zero(currency: "") + } + exchange = exc } else { - let currency = exc.scopeInfo.currency - amountToTransfer.setCurrency(currency) - // is already Amount.zero(currency: "") + exchange = nil } - exchange = exc - } catch { // TODO: error - symLog.log(error.localizedDescription) - symLog.log(error.localizedDescription) - model.showError(.error(error)) - controller.playSound(0) - exchange = nil } } } diff --git a/TalerWallet1/Views/Transactions/TransactionSummaryV.swift b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift @@ -28,14 +28,14 @@ struct TransactionSummaryV: View { private let symLog = SymLogV(0) let stack: CallStack let transactionId: String - let reloadAction: ((_ transactionId: String) async throws -> Transaction) + let reloadAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Transaction) let navTitle: String? let doneAction: ((_ stack: CallStack) -> Void)? - let abortAction: ((_ transactionId: String) async throws -> Void)? - let deleteAction: ((_ transactionId: String) async throws -> Void)? - let failAction: ((_ transactionId: String) async throws -> Void)? - let suspendAction: ((_ transactionId: String) async throws -> Void)? - let resumeAction: ((_ transactionId: String) async throws -> Void)? + let abortAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Void)? + let deleteAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Void)? + let failAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Void)? + let suspendAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Void)? + let resumeAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Void)? @Environment(\.colorScheme) private var colorScheme @Environment(\.colorSchemeContrast) private var colorSchemeContrast @@ -50,12 +50,10 @@ struct TransactionSummaryV: View { @State var viewId = UUID() func loadTransaction() async { - do { - let reloadedTransaction = try await reloadAction(transactionId) + if let reloadedTransaction = try? await reloadAction(transactionId, false) { symLog.log("reloaded transaction: \(reloadedTransaction.common.txState.major)") withAnimation() { transaction = reloadedTransaction; viewId = UUID() } // redraw - } catch { - symLog.log(error.localizedDescription) + } else { withAnimation() { transaction = Transaction(dummyCurrency: DEMOCURRENCY); viewId = UUID() } } } diff --git a/TalerWallet1/Views/Transactions/TransactionsListView.swift b/TalerWallet1/Views/Transactions/TransactionsListView.swift @@ -15,7 +15,7 @@ struct TransactionsListView: View { let transactions: [Transaction] let showUpDown: Bool let reloadAllAction: (_ stack: CallStack) async -> () - let reloadOneAction: ((_ transactionId: String) async throws -> Transaction) + let reloadOneAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Transaction) @State private var viewId = UUID() @State private var upAction: () -> Void = {} @@ -84,7 +84,7 @@ struct TransactionsArraySliceV: View { let stack: CallStack let scopeInfo: ScopeInfo let transactions: [Transaction] - let reloadOneAction: ((_ transactionId: String) async throws -> Transaction) + let reloadOneAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Transaction) @EnvironmentObject private var model: WalletModel var body: some View {