The port runs on Android and iOS and is feature-complete; the native Android app is superseded but kept, since it is still the only version that has recorded real rides. rippr-flutter-1.0-debug.apk is package com.rippr.port, deliberately different from the native com.rippr so both install side by side. Recording the same ride on both at once is the strongest available check that the port is faithful. Added INSTALL.md covering both platforms. Android is a one-line adb install; iOS has no APK equivalent and must be built and signed through Xcode with a free Apple ID, which gives a 7-day profile. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3.7 KiB
T26 — iOS release readiness
What App Review will look at, and what is already in place. Background-location apps get
more scrutiny than most, and the research in docs/PORT_RESEARCH.md names unclear
privacy disclosure as the leading rejection cause.
Status: configured, not submitted. Nothing here has been through review.
Guideline 5.1.1 — data privacy and transparency
Rejection cause: generic usage strings like "This app needs location".
Already in ios/Runner/Info.plist, written specifically:
| Key | Says |
|---|---|
NSLocationWhenInUseUsageDescription |
Records the GPS track of your ride so you can see route, speed and distance afterwards. Nothing is recorded until you press Start. |
NSLocationAlwaysAndWhenInUseUsageDescription |
Keeps recording while the phone is in your pocket or the screen is off, so a ride you started is captured beginning to end. Recording stops the moment you press Stop. |
Both name what is collected, why, and when it stops. That last clause matters — it is the difference between "an app that wants your location" and "a recorder you control".
App Privacy nutrition labels
Declare, and make sure it stays true:
- Location → Precise Location, linked to the user? No. Used for App Functionality only.
- No data collected for tracking, no advertising identifiers, no analytics SDKs.
- Data is not transmitted off-device by default. The uploader exists but has no UI and no endpoint configured; it is inert unless someone sets one deliberately.
If a server ever ships (the v3 group-ride idea), these labels must change before it does. Undisclosed background transmission is a straightforward rejection.
Guideline 2.1 — completeness and background stability
The exposure is crashing on background resume. Mitigations in place:
- Recording state lives in the database, so resuming after suspension reads real state rather than guessing.
restoreAfterProcessDeathruns at startup and is covered by four tests, including the crash-gap guard.- Every upload failure path is swallowed; the network cannot stop a recording.
- Database write failures are caught per batch — losing points beats losing the app.
Still unproven: what iOS actually does when the app is suspended while stationary. That is item I3 in REAL-RIDE-CHECKLIST.md and it must be answered before submission.
Guideline 4.2 — minimum functionality
Not a realistic risk: native Flutter UI, real hardware integration, offline-first storage, no web view anywhere.
Before submitting
- Switch the bundle id from
com.rippr.porttocom.rippr(T27). The.portsuffix exists only so the native app can be installed alongside during the port. CFBundleNameis still the generated lowercaserippr;CFBundleDisplayNameis alreadyRippr. Make them consistent.- App icon and launch screen — still Flutter defaults. The native app's adaptive icon
artwork lives in
~/dojo/rippr/design/and needs re-exporting at iOS sizes. - Run REAL-RIDE-CHECKLIST.md on a real iPhone, especially I3.
- Record a demo video of a real ride for the review notes. Background-location apps are frequently asked to justify the entitlement; a video pre-empts a rejection round.
flutter build ipa --releaseand confirm the release build works — everything so far has been debug.
Known parity gap to disclose internally
The notification cannot carry actions, so the native app's Pause/Resume buttons in the shade are absent on both platforms. Not an App Review issue; it is a feature difference the T27 audit must record.