View Issue Details

IDProjectCategoryView StatusLast Update
0008851Talerwallet (iOS App)public2024-07-25 22:12
ReporterFlorian Dold Assigned ToMarcS Resolution deadline
ImplementerReviewer 
Release signed byDeployed by 
VerifierCommunicator 
Data protection authority notification requiredNo  
CSIRT notification requiredNo  
Estimated effort (hours)Actual effort (hours)0 
Fast-trackNo
Work packagenone
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.

Required notifications

Address or linkRemarkAdded byNotifiedActions

Relationships

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

Activities

MarcS

2024-05-16 05: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 05: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 07: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 15: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 10: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 14: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 ModifiedUsernameFieldChange
2024-05-15 22:34Florian DoldNew Issue
2024-05-15 22:34Florian DoldStatusnew => assigned
2024-05-15 22:34Florian DoldAssigned To => MarcS
2024-05-15 22:34Florian DoldIssue generated from: 0008850
2024-05-16 05:07MarcSNote Added: 0022432
2024-05-16 05:07MarcSAssigned ToMarcS => Florian Dold
2024-05-16 15:02Florian DoldAssigned ToFlorian Dold => MarcS
2024-05-20 05:47MarcSNote Added: 0022441
2024-06-18 07:38MarcSNote Added: 0022662
2024-06-18 07:38MarcSAssigned ToMarcS => Florian Dold
2024-06-18 15:49Florian DoldNote Added: 0022665
2024-06-18 15:49Florian DoldAssigned ToFlorian Dold => MarcS
2024-06-18 15:49Florian DoldStatusassigned => feedback
2024-06-20 10:31MarcSNote Added: 0022685
2024-06-26 14:21Florian DoldStatusfeedback => assigned
2024-07-09 14:39MarcSStatusassigned => informing
2024-07-09 14:39MarcSResolutionopen => suspended
2024-07-09 14:39MarcSNote Added: 0022801
2024-07-09 14:42MarcSRelationship addedrelated to 0009007
2024-07-25 22:11Christian GrothoffFixed in Version => 0.12
2024-07-25 22:12Christian GrothoffStatusinforming => closed