View Issue Details

IDProjectCategoryView StatusLast Update
0011954Talerwallet (iOS App)public2026-11-05 15:12
Reporterbot-cg [agent] Assigned ToResolution deadline
ImplementerReviewer 
Release signed byDeployed by 
VerifierCommunicatorCM_7  
Data protection authority notification requiredNo  
CSIRT notification requiredNo  
Estimated effort (hours)Actual effort (hours)0 
Fast-trackNo
Work packagenone
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Summary0011954: OIM never appears when the app is launched already in landscape: the orientation at appear is not reported
DescriptionStart the wallet while already holding the phone in landscape and the OIM
presentation never appears. It only shows up after rotating to portrait and
back to landscape.

Cause
-----
`MainView.swift:328` activates OIM from `.onRotate`:

    .onRotate { newOrientation in
        controller.setOIMmode(for: newOrientation, isSheetActive)
        ...
    }

and `TalerCommon/ViewModifier/View+DeviceRotation.swift` only reacts to a
change:

    content
        .onAppear() // SwiftUI bug: view modifiers do not work with
                        // onReceive() unless you first add onAppear()
        .onReceive(... UIDevice.orientationDidChangeNotification ...) { _ in
            action(UIDevice.current.orientation)
        }

That bare `.onAppear()` is a workaround for an unrelated SwiftUI problem and
takes no action of its own, so the orientation a view *appears* in is never
reported — only later changes are. `Controller.setOIMmode` therefore never
runs at launch, `oimModeActive` stays false, and
`BalancesListView`/`TransactionsListView` do not add their OIM overlay.

Measured
--------
An app launched directly into landscapeRight, with a non-empty balances list
on screen (`screenSize [874, 402]`, navTitle "Balances"), left every file
under `TalerWallet1/Views/OIM/` at 0.0% line coverage — 4,289 instrumented
lines, about a tenth of the app, none of it entered. The same build enters
OIM normally when the device is rotated after launch.

Suggested fix (patch attached)
------------------------------
Report the orientation on appear as well:

    .onAppear { action(UIDevice.current.orientation) }

`MainView` is the only caller of `onRotate`, so nothing else changes
behaviour. This also removes the need for the bare `.onAppear()`, since the
new one serves the same purpose.

Why it matters beyond the missing presentation: this is also what makes the
OIM code unreachable for UI automation that launches the app in a fixed
orientation, which is how a test harness normally starts it.

How to reproduce
----------------
1. Fresh build of the GNU_Taler scheme (OIM is in its compilation
   conditions) on an iPhone simulator.
2. Give the wallet a balance so the balances list is non-empty.
3. Put the simulator in landscape *before* launching the app, e.g.
   `xcrun simctl ui <device> appearance` is not needed -- set the device
   orientation and then launch.
4. The balances list appears without the OIM overlay. Rotate to portrait
   and back to landscapeRight: the overlay appears.

Filed by an agent (bot-cg) on behalf of Christian Grothoff, from an
automated UI exploration campaign. Left unassigned deliberately.
TagsNo tags attached.
Attached Files
report-orientation-on-appear.diff (1,309 bytes)   
diff --git a/TalerCommon/ViewModifier/View+DeviceRotation.swift b/TalerCommon/ViewModifier/View+DeviceRotation.swift
index c059c2a1..d011856b 100644
--- a/TalerCommon/ViewModifier/View+DeviceRotation.swift
+++ b/TalerCommon/ViewModifier/View+DeviceRotation.swift
@@ -32,7 +32,16 @@ struct DeviceRotationViewModifier: ViewModifier {
 
     func body(content: Content) -> some View {
         content
-            .onAppear()     // SwiftUI bug: view modifiers do not work with onReceive() unless you first add onAppear()
+            // SwiftUI bug: view modifiers do not work with onReceive()
+            // unless you first add onAppear().
+            //
+            // Report the orientation the view appears in, too, not only
+            // later changes.  Without this a view that is already in
+            // landscape when it appears never hears about it: the app
+            // launched in landscapeRight leaves `oimModeActive` false, so
+            // the OIM presentation is missing until the user rotates away
+            // and back again.
+            .onAppear { action(UIDevice.current.orientation) }
             .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
                 action(UIDevice.current.orientation)
             }

Required notifications

Address or linkRemarkAdded byNotifiedActions

Activities

Issue History

Date ModifiedUsernameFieldChange
2026-11-05 15:12bot-cgNew Issue
2026-11-05 15:12bot-cgFile Added: report-orientation-on-appear.diff