21 September 2026 · Hotwire Native iOS 1.2.2 & dev.hotwire 1.2.4 · 849 Swift + 817 Kotlin
mobile/ios/C12 and mobile/android/C12 — 15 Swift files
(849 lines, hotwire-native-ios 1.2.2, iOS 16.4+, marketing version 1.1.1) and
13 Kotlin files (817 lines, dev.hotwire 1.2.4, minSdk 28, targetSdk 35).
Every finding below cites a file, a key or a value that was read directly.c12_core_ios — bundle com.rolemodelsoftware.C12CORE, a 241-line
turbo-ios prototype from 2021. That repository is not what C12 ships, and every code-level
finding taken from it has been withdrawn. The strategic sections were unaffected and are now verified
against the real source.
Two shipping apps, 849 lines of Swift and 817 lines of Kotlin, both on current Hotwire Native, both with a real bridge, remote path configuration, working push that routes to the exact screen, and native document viewing. This is a well-built pair of apps, and the sections below should be read in that light.
Two things are true at once. First, the two apps have drifted apart — a different second tab, two different brand colours, two different bridge component sets, and a dark mode that one platform declares and neither delivers. Second, and more importantly, neither app has stepped outside itself. Searching both codebases for WidgetKit, ActivityKit, App Intents, Glance, PassKit, VisionKit, EventKit, CarPlay and the on-device model frameworks returns nothing at all.
So the work splits cleanly. Converge the two apps — one palette, one tab set, one appearance decision, real deep links. Then spend the native budget on the four places the phone beats a web view for this particular membership: meeting day, glanceable presence, the monthly report, and private on-device intelligence.
hotwire-native-ios 1.2.2, Android runs dev.hotwire 1.2.4. The team followed the framework through its rename and its 1.x rewrite rather than letting a beta calcify. That is unusual and it is the reason everything below is a next step rather than a rescue./api/v2/path_configuration.json. Routing and presentation rules change on a web deploy, with no App Store review in the way. Many teams never get here.urlStack, and both apps route the member straight to the right page inside the app. Tapping “Marcus replied” lands on Marcus’s reply, signed in.enableEdgeToEdge(), enableOnBackInvokedCallback="true" for predictive back, IME window insets handled. It is not an iOS app ported across.setTabBarHidden API. Someone thought about the first run./numbers to a view_controller. The hook for going fully native on a screen exists and has been used.Where the two apps stand today, organised by what matters most.
These are the things a C12 member meets in normal use. None need new features — they are unfinished edges on an otherwise solid app.
webcredentials:c12app.com — password autofill, not link handling — and the Android manifest has no autoVerify intent filter.tintColor = primaryColor and unselectedItemTintColor = primaryColor.withAlphaComponent(0.6).Theme.Material3.DayNight and then hard-codes windowBackground, colorSurface and colorOnSurface to white and black. iOS never reads userInterfaceStyle.print("Couldn’t register remote notifications") on iOS, Log.d on Android.launchMode="singleInstance" on the single activity.com.google.android.gms.permission.AD_ID.The most useful thing this assessment found. iOS and Android have drifted, and each difference is small enough to fix in a sprint and awkward enough to be worth fixing.
/cadre. Android ships Resources → /resource_collections.UIColor(red: 0.00, green: 0.22, blue: 0.28) — #003847. Android sets color_brand to #2E3E46.#335C66 for buttons and #DEE5E7 for the tab indicator.ButtonComponent, CloseButtonComponent and EnableNotificationsComponent. Android registers seven, including a NavbarComponent iOS does not have./meeting_members, /transfer, /withdraw, /assign, /edit_staffing and a native /numbers screen. The Android file has none of those.DayNight and then overrides it to light. iOS never opts in at all.Read directly from C12.swift, Tabs.kt, SceneDelegate.swift and colors.xml.
/cadre/resource_collections#003847 · UIColor(0.00, 0.22, 0.28)#2E3E46 · color_brand#335C66 buttons · #DEE5E7 tab indicatorOne product currently renders in five colours across two apps, none of which is a C12 brand colour. Contrast ratios below are against WCAG AA.
Table stakes rather than ambitions: a current Android target, a release you can identify, tests that catch regressions, and an app that does not crash on a bad payload.
1.12.0, no Material 3 Expressive adoption.aps-environment to development.production. If it does not, push silently fails for every App Store build.versionName is still "1.0" while the store lists a later build.test or androidTest source set on Android.window!, urlStack.last!, Bundle.main.url(…)! and six UIImage(systemName:)! calls.urlStack from the server ends the session instead of falling back to the notifications list.This is the pitch, and it is now measured rather than assumed. C12 members are chief executives who gather one full day a month and carry confidential business and personal detail in this app. That combination maps almost exactly onto what iOS and Android added over the last two years — and neither app references any of it.
WidgetKit, ActivityKit, AppIntents, androidx.glance, AppWidgetProvider, PassKit, VisionKit, EventKit, CarPlay and FoundationModels returns zero matches.Twelve principles evaluated against what the shipping code actually does.
urlStack and both apps route to the exact screen, already signed in.applinks entitlement and no verified App Link filter. Emailed links hand members to a browser and a second sign-in.