View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0012141 | Taler | wallet (iOS App) | public | 2026-11-15 15:47 | 2026-11-15 15:47 |
| Reporter | bot-cg [agent] | ||||
| Priority | normal | Severity | major | ||
| Status | new | ||||
| Summary | 0012141: taler://add-exchange link ends on "Scanning..." forever: ExchangeListView clears URLSheet's passedURL and is replaced by the loading view (patch attached) | ||||
| Description | Opening a taler://add-exchange/ link (QR code or link from another app) does not offer to add the payment service. The sheet comes up, shows the list of payment services for an instant, and then shows "Loading... / Scanning..." with a Cancel button and stays there. The "Add payment service" prompt, which is what the link is for, never becomes usable. Steps (iOS 27.2 simulator, fresh wallet, current master): 1. Start the wallet; it shows "Welcome to Taler Wallet!". 2. Open taler://add-exchange/<host>/ (any exchange; here a test exchange). 3. A sheet opens. Expected: the payment-service list with the "Add payment service" alert up and the address prefilled. Actual: "Scanning..." (see add-exchange-stuck-scanning.jpg, taken 90 s after the link was opened). The app log shows the link being recognised and the list view appearing again and again, never settling: saveURL: addExchange 16:22:14.460 switching from 10 to 72 ExchangeListView.swift:211 16:22:56.418 72 stays ExchangeListView.swift:211 16:23:38.531 72 stays ExchangeListView.swift:211 Cause. URLSheet shows the view for a link only while both of its state variables are set, and falls back to the "Scanning..." view otherwise: if let urlCommand, let passedURL { switch urlCommand { case .addExchange: ExchangeListView(stack: stack.push(), url: $passedURL) ... } else { LoadingView(... message: "Scanning...") .task(id: urlToOpen) { passUrlOnce() } } ExchangeListView receives URLSheet's passedURL as a binding and clears it as soon as it has read it (ExchangeListView.swift, the .task on the list): if let newUrl = url { newExchange = newUrl.trimmedString showAlert = true url = nil // <- this is URLSheet.passedURL } Clearing it makes URLSheet's condition false, so URLSheet removes the ExchangeListView it has just shown -- together with the alert it was about to present -- and puts the "Scanning..." view back. When the sheet was opened from onOpenURL (sheetURL), the Scanning view's task parses the link again, the list view is created again, clears the binding again, and so on. Fix (add-exchange-uri-stuck-scanning.diff, attached): remember in the list view's own state that the link has been consumed, and leave the binding alone. The Settings entry passes .constant(nil) and is unaffected. Found by the UI fuzz harness (scenario exchange-add, 2026-11-15); the scenario waits 120 s for the "Add payment service" prompt and never sees it. The patch is not yet build-verified. | ||||
| Tags | No tags attached. | ||||
| Attached Files | 12141-add-exchange-uri-stuck-scanning.diff (1,405 bytes)
diff --git a/TalerWallet1/Views/Settings/Exchange/ExchangeListView.swift b/TalerWallet1/Views/Settings/Exchange/ExchangeListView.swift
index 2017f245..3624d6c3 100644
--- a/TalerWallet1/Views/Settings/Exchange/ExchangeListView.swift
+++ b/TalerWallet1/Views/Settings/Exchange/ExchangeListView.swift
@@ -41,6 +41,7 @@ struct ExchangeListView: View {
#endif
@State private var showAlert: Bool = false
+ @State private var urlTaken: Bool = false
@State private var newExchange: String = EXCHANGE + DEMO // without HTTPS
func checkExchanges() {
@@ -74,10 +75,12 @@ struct ExchangeListView: View {
.navigationTitle(TITLE_EXCHANGES)
.navigationBarItems(trailing: plusButton)
.task {
- if let newUrl = url {
+ if let newUrl = url, !urlTaken {
+ // Do not clear `url`: it is URLSheet's passedURL, and
+ // clearing it replaces this view by "Scanning..." for good
+ urlTaken = true
newExchange = newUrl.trimmedString
showAlert = true
- url = nil
} else {
checkExchanges()
}
| ||||