View Issue Details

IDProjectCategoryView StatusLast Update
0008851Talerwallet (iOS App)public2024-07-26 00:12
ReporterFlorian Dold Assigned ToMarcS  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionsuspended 
Target Version0.12Fixed in Version0.12 
Summary0008851: ios wallet should call hintNetworkAvailability
DescriptionThe new wallet-core request

  hintNetworkAvailability({isNetworkAvailable: boolean})

should be used to tell wallet-core about network availability.

In case the network becomes available again, all pending tasks are retried immediately.
In the future, when the network becomes unavailable, wallet-core might stop emitting certain errors or not retry certain network requests.
TagsNo tags attached.

Relationships

related to 0009007 assignedMarcS iOS wrongly reports a network failure when wallet-core cancels a long-poll network call (~ 4-6 hours) 

Activities

MarcS

2024-05-16 07:07

developer   ~0022432

Apple recommends the following workflow:
1) don't start with any availability calls, but just try to connect your target
2) if iOS returns a network error, start monitoring internet connection (task)
3) iOS will call a closure with the status whenever that changes (active, inactive, requiresConnection)
4) when the status switches to active (or requiresConnection), stop monitoring and goto 1)

I already implemented all necessary code: wallet-core needs to call checkInternetConnection() on 2)
when the status is no longer inactive, the iOS wallet will stopCheckingConnection() and notify wallet-core with a call to hintNetworkAvailability(isNetworkAvailable: true) that it can resume with 1)
(in case of 'requiresConnection' that may immediately result in another network error, but we must try, it can as well succeed) ==> for wallet-core 'inactive' means isNetworkAvailable=false and NOT 'inactive' means true

MarcS

2024-05-20 07:47

developer   ~0022441

I added calls to hintNetworkAvailability directly into the native http routine.
Workflow is:

1) wallet-core calls request_create()

2) iOS wallet spawns an asynchronous URLSessionDataTask and returns

3) Either the dataTask returns a response…
3a) with data: iOS wallet returns the data to wallet-core, and also status and response headers
3b) but no data (probably a failure): iOS wallet returns nil, status and response headers

4) …or only an error (no response): iOS wallet first calls hintNetworkAvailability(false) asynchronously, and after that returns starts monitoring the internet connection (again asynchronously, but doesn't wait for that to finish) and finally returns the error with status = 0 to wallet-core
4a) when the network is available again, iOS wallet stops monitoring the internet connection and calls hintNetworkAvailability(true).

5) when wallet-core cancels the dataTask before 3), it will return 3b) with an error in the domain NSURLErrorDomain with the code NSURLErrorCancelled - which wallet-core can ignore.

The monitoring task started in the middle of 4) can at any time asynchronously call hintNetworkAvailability()with isNetworkAvailable = false (again) or = true, even before the dataTask returns the result at the end of 4). The only timing guaranteed is that the very first hintNetworkAvailability(false) comes first since the monitor is only started after that returned.

When the error was not caused by a loss of internet connection, wallet-core will nevertheless receive one hintNetworkAvailability(false) followed by one hintNetworkAvailability(true), since I don't examine the error code - yet.

Possible errors (more than 60) are documented here: (https://developer.apple.com/documentation/foundation/1508628-url_loading_system_error_codes)
We should probably match them to Android's network error codes, and define our own (localized) error messages to show to the user.
There are some interesting codes such as NSURLErrorCallIsActive (https://developer.apple.com/documentation/foundation/1508628-url_loading_system_error_codes/nsurlerrorcallisactive)
"A connection was attempted while a phone call was active on a network that doesn’t support simultaneous phone and data communication, such as EDGE or GPRS."

for which the best reaction is don't show to the user (who is making the phone call), but just wait until the monitor will call hintNetworkAvailability(true) after the phone call ends and then try the failed connection again.
Wait - what if the user switched from the phone app to Taler Wallet and tries to pay something without ending the call first? In that case we should show the error "Cannot connect to the internet while a phone call is active" to let the user know what to do...

So we need to group the possible errors:
1) alert the user immediately
2) try repeating some times before alerting the user
3) silently retry without alerting the user
did I miss another strategy?

MarcS

2024-06-18 09:38

developer   ~0022662

The iOS part (call hintNetworkAvailability) is done and already in the AppStore (0.11.2). However, we still need the combined errors (see my last note) for a good user experience, and all wallets need to act differently on the 3 error groups.

Florian Dold

2024-06-18 17:49

manager   ~0022665

I'm confused. Do you want the *UI* to show some error banner based on the last failed HTTP request, or are you suggesting some wallet-core feature/improvement here?

MarcS

2024-06-20 12:31

developer   ~0022685

We decided to move the whole screen down and show a banner on top when the network is not available, to inform the user that currently actions are not possible until the network is available again.

MarcS

2024-07-09 16:39

developer   ~0022801

We found that iOS wrongly reported a network failure when wallet-core cancelled a long-poll network call - which of course stopped wallet-core from starting any new network calls.
We need to debug that - but since otherwise the code is implemented and working, I close this bug here and open a new one for the cancel fault.

Issue History

Date Modified Username Field Change
2024-05-16 00:34 Florian Dold New Issue
2024-05-16 00:34 Florian Dold Status new => assigned
2024-05-16 00:34 Florian Dold Assigned To => MarcS
2024-05-16 00:34 Florian Dold Issue generated from: 0008850
2024-05-16 07:07 MarcS Note Added: 0022432
2024-05-16 07:07 MarcS Assigned To MarcS => Florian Dold
2024-05-16 17:02 Florian Dold Assigned To Florian Dold => MarcS
2024-05-20 07:47 MarcS Note Added: 0022441
2024-06-18 09:38 MarcS Note Added: 0022662
2024-06-18 09:38 MarcS Assigned To MarcS => Florian Dold
2024-06-18 17:49 Florian Dold Note Added: 0022665
2024-06-18 17:49 Florian Dold Assigned To Florian Dold => MarcS
2024-06-18 17:49 Florian Dold Status assigned => feedback
2024-06-20 12:31 MarcS Note Added: 0022685
2024-06-26 16:21 Florian Dold Status feedback => assigned
2024-07-09 16:39 MarcS Status assigned => resolved
2024-07-09 16:39 MarcS Resolution open => suspended
2024-07-09 16:39 MarcS Note Added: 0022801
2024-07-09 16:42 MarcS Relationship added related to 0009007
2024-07-26 00:11 Christian Grothoff Fixed in Version => 0.12
2024-07-26 00:12 Christian Grothoff Status resolved => closed