taler-ios

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

commit bcc52d9066ffda6af313b4b85a20c516715105fe
parent 417a07db02add508e30837de43416acfda6b968e
Author: Marc Stibane <marc@taler.net>
Date:   Mon, 20 May 2024 07:55:59 +0200

Networking: hintNetworkAvailability()

Diffstat:
MTalerWallet1/Controllers/Controller.swift | 13++++++++++++-
MTalerWallet1/Model/WalletModel.swift | 43++++++++++++++++++++++++++++++++-----------
MTalerWallet1/Quickjs/QuickDataTask.swift | 30+++++++++++++++++-------------
MTalerWallet1/Quickjs/quickjs.swift | 6+++---
4 files changed, 64 insertions(+), 28 deletions(-)

diff --git a/TalerWallet1/Controllers/Controller.swift b/TalerWallet1/Controllers/Controller.swift @@ -60,7 +60,18 @@ class Controller: ObservableObject { } self.logger.log("Internet connection is \(status)") DispatchQueue.main.async { - self.isConnected = (path.status == .satisfied) + if path.status == .unsatisfied { + self.isConnected = false + Task.detached { + await WalletModel.shared.hintNetworkAvailabilityT(false) + } + } else { + self.stopCheckingConnection() + self.isConnected = true + Task.detached { + await WalletModel.shared.hintNetworkAvailabilityT(true) + } + } } } self.logger.log("Start monitoring internet connection") diff --git a/TalerWallet1/Model/WalletModel.swift b/TalerWallet1/Model/WalletModel.swift @@ -67,17 +67,26 @@ class WalletModel: ObservableObject { throw error } } +} +// MARK: - +/// A request to tell wallet-core about the network. +fileprivate struct NetworkAvailabilityRequest: WalletBackendFormattedRequest { + struct Response: Decodable {} + func operation() -> String { "hintNetworkAvailability" } + func args() -> Args { Args(isNetworkAvailable: isNetworkAvailable) } - 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, viewHandles: viewHandles) + var isNetworkAvailable: Bool + + struct Args: Encodable { + var isNetworkAvailable: Bool } - /// get the specified transaction from Wallet-Core. No networking involved - @MainActor func getTransactionByIdM(_ transactionId: String, viewHandles: Bool = false) - async throws -> Transaction { // M for MainActor - return try await getTransactionByIdT(transactionId, viewHandles: viewHandles) // call GetTransactionById on main thread +} + +extension WalletModel { + func hintNetworkAvailabilityT(_ isNetworkAvailable: Bool = false) async { + // T for any Thread + let request = NetworkAvailabilityRequest(isNetworkAvailable: isNetworkAvailable) + _ = try? await sendRequest(request, 0) } } // MARK: - @@ -93,6 +102,20 @@ fileprivate struct GetTransactionById: WalletBackendFormattedRequest { var transactionId: String } } + +extension WalletModel { + 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, viewHandles: viewHandles) + } + /// get the specified transaction from Wallet-Core. No networking involved + @MainActor func getTransactionByIdM(_ transactionId: String, viewHandles: Bool = false) + async throws -> Transaction { // M for MainActor + return try await getTransactionByIdT(transactionId, viewHandles: viewHandles) // call GetTransactionById on main thread + } +} // MARK: - /// The info returned from Wallet-core init struct VersionInfo: Decodable { @@ -257,7 +280,6 @@ extension WalletModel { } } // MARK: - - fileprivate struct DevExperimentRequest: WalletBackendFormattedRequest { func operation() -> String { "applyDevExperiment" } func args() -> Args { Args(devExperimentUri: talerUri) } @@ -278,4 +300,3 @@ extension WalletModel { _ = try await sendRequest(request, 0, viewHandles: viewHandles) } } - diff --git a/TalerWallet1/Quickjs/QuickDataTask.swift b/TalerWallet1/Quickjs/QuickDataTask.swift @@ -134,19 +134,23 @@ class QuickDataTask: NSObject { let responseInfoPtr = UnsafeMutablePointer<JSHttpResponseInfo>(&responseInfo) responseCb(responseCbCls, responseInfoPtr) } - } else { // TODO: pass error to walletCore - var errmsg = "No http response from \(url)" - logger.error("⁉️ \(self.requestID, privacy: .public) \(method, privacy: .public) \(errmsg, privacy: .public)") - var errmsg_p0 = UnsafeMutablePointer<CChar>(mutating: errmsg.cString(using: .utf8)) - var responseInfo = JSHttpResponseInfo(request_id: self.requestID, - status: 0, - errmsg: errmsg_p0, - response_headers: nil, - num_response_headers: 0, - body: nil, - body_len: 0) - let responseInfoPtr = UnsafeMutablePointer<JSHttpResponseInfo>(&responseInfo) - responseCb(responseCbCls, responseInfoPtr) + } else { // pass error to walletCore + Task.detached { + var errmsg = "No http response from \(url)" + logger.error("⁉️ \(self.requestID, privacy: .public) \(method, privacy: .public) \(error, privacy: .public) \(errmsg, privacy: .public)") + await WalletModel.shared.hintNetworkAvailabilityT(false) + Controller.shared.checkInternetConnection() // TODO: pass error to walletCore + var errmsg_p0 = UnsafeMutablePointer<CChar>(mutating: errmsg.cString(using: .utf8)) + var responseInfo = JSHttpResponseInfo(request_id: self.requestID, + status: 0, + errmsg: errmsg_p0, + response_headers: nil, + num_response_headers: 0, + body: nil, + body_len: 0) + let responseInfoPtr = UnsafeMutablePointer<JSHttpResponseInfo>(&responseInfo) + responseCb(responseCbCls, responseInfoPtr) + } } requests[requestID] = nil } diff --git a/TalerWallet1/Quickjs/quickjs.swift b/TalerWallet1/Quickjs/quickjs.swift @@ -52,8 +52,8 @@ public class Quickjs { // acts as singleton, since only one instance ever e public weak var messageHandler: QuickjsMessageHandler? var logger: Logger - @Atomic(default: 0) - private var lastRequestID: Int32 + @Atomic(default: 0) // boilerPlate around NSLock… + private var lastRequestID: Int32 // …to safeguard increments private var requests: [Int32: QuickDataTask] = [:] private lazy var urlSession: URLSession = { @@ -84,7 +84,7 @@ public class Quickjs { // acts as singleton, since only one instance ever e func reqCreate(_ request: URLRequest, _ responseCb: JSHttpResponseCb?, _ responseCbCls: Optional<UnsafeMutableRawPointer>) -> Int32 { - let requestID = $lastRequestID.atomicIncrement() + let requestID = $lastRequestID.atomicIncrement() // ensure requestID is unique let quickDataTask = QuickDataTask(urlSession: urlSession, request: request, requestID: requestID,