commit bcc52d9066ffda6af313b4b85a20c516715105fe
parent 417a07db02add508e30837de43416acfda6b968e
Author: Marc Stibane <marc@taler.net>
Date: Mon, 20 May 2024 07:55:59 +0200
Networking: hintNetworkAvailability()
Diffstat:
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,