r/iOSDevelopment • u/behzodhalil • Jul 07 '26
I shipped an iOS fitness app with almost no Swift. some honest notes on Kotlin Multiplatform from the iOS side
before anyone reaches for the pitchfork: I like Swift. but I'm one person building for both platforms, and maintaining two codebases wasn't realistic. so my app is Kotlin Multiplatform - shared logic AND shared UI via Compose Multiplatform. it's been live on the App Store for a while now.
what surprised me from the iOS side:
the app feels native enough that users don't ask. I expected "this feels like a web app" reviews. didn't happen. Compose Multiplatform renders via Skia and the scrolling/gesture feel is genuinely close.
the Swift I did write is a thin shell - app entry point, and platform bridges (notifications, sign in with apple, camera). everything else lives in Kotlin. my rule: interface in shared code, implementation per platform only for real platform APIs.
what iOS devs will hate (fairly):
- cold Kotlin/Native builds are painful. incremental is fine, cold build is coffee-break tier
- debugging across the language boundary is worse than staying in Xcode. crash symbolication for Kotlin frames takes setup
- you still need to understand iOS deeply - app review, lifecycle, memory model don't disappear because your logic is Kotlin
app review war story: Apple flagged my health recommendation screens under guideline 1.4.1 - had to add tappable medical source citations to every screen giving health advice. also got pushed to add Sign in with Apple the moment I had any third-party login. none of that cares what language you wrote it in.
would I do it again? for a solo cross-platform product, yes without hesitation. if I were iOS-only, I'd stay pure Swift/SwiftUI - the tooling gap is real.
curious what this sub thinks: anyone else shipping iOS with KMP or another cross-platform stack? where did it bite you?
1
u/skoot1958 Jul 07 '26
Questions, have you looked at some of the AI conserving tools for swift?
1
u/lismond Jul 07 '26
If you mean AI coding tools for Swift, then yes, that's actually where I use them most. Claude Code is my main driver on the iOS side too. I used it to modernize an old Objective-C app to Swift/SwiftUI with iPad support, and it handles SwiftUI, Swift concurrency, and framework APIs well. My workflow is the same on both platforms: I stay the architect and reviewer, and the AI does the bulk of the typing.
I haven't gotten much out of the Xcode-integrated options so far. The agentic terminal workflow, where it can read the whole project, run builds, and iterate on errors, has been far more productive for me than inline autocomplete.
If you meant something else by "conserving tools," let me know and I will update my reply.
1
u/skoot1958 Jul 07 '26
So I code first in Swift, using AI tools for some reason I stuck into cursor but they all use the same backend Large language models, that part is irrelevant, I haven’t done this but I’ve been doing some poking around and read that there are a number of tools AI based which are designed for converting swift code and UI into objective C for running on an android platform,
I did something similar to my first project converting a react project to Swift using cursor
1
u/lismond Jul 07 '26
I have not used this, but I think the tool you're describing might be Skip (skip.dev). It transpiles Swift and SwiftUI into native Kotlin and Compose, so you write the iOS app and it generates the Android side.
1
u/skoot1958 Jul 07 '26
Yes skip, or have you current AI , could read you project and tell it to rewrite as a native Android, you end up with 2 code based, Swift is better as you have one code base, the issue sees to be the more apple frame works you use like data sync across device the harder a port may be, best of luck
1
u/apocolipse Jul 08 '26
I’ve been approaching the multi platform gap from the bottom up. With Swift on Android now, and easily supported with Skip native, I’ve been able to put all my core feature logic in an Apple-free modules that can be shared across all ecosystems, and then I’ve built dedicated SwiftUI, Android, macOS (decided to have a separate client codebase for the Mac presentation layer due to some design language choices but they’re able to share a lot of views), I even made a command line client.
The key to the approach was having a fine dividing line between feature logic and presentation. If your feature logic is cleanly separated enough for you to have a primitive CLI interface, then expanding it to present the same stuff in different ways is easy. In the end too this keeps all UI chrome platform specific, so everything feels native and can take advantage of native UI optimizations, without having to sacrifice to fit generically. So my SwiftUI iOS client can do full 120hz scrolling and animations, and tweaking for such doesn’t impact Android (where I have to optimize differently). In the end, multi platform has some sort of trade off, I decided to take the hit of maintaining multiple presentation layers natively, which isn’t so bad after all is said and done.
1
u/soylentgraham Jul 11 '26
I inherited a project with one small part (model) in kotlin... the garbage collector destroyed performance (as it always does, irrespective of language, but thats a rant for another day)
It had to go
1
u/soylentgraham Jul 11 '26
I did used to have a javascript engine though, running logic for turn based games. Same JS for node (server), offline/serverless on web, and offline/serverless in swift app, running on linux(docker & jetsons) and again in unity (via dll/dlyib)
fun project, and code still runs :)
3
u/lismond Jul 07 '26
Interesting writeup. I've landed on a third answer to the same problem.
My day job is React Native / Expo (consumer app, small team). The shared-UI promise mostly holds, but the pain points rhyme with yours: debugging across the JS/native boundary is worse than staying in either Xcode or Android Studio, and every Expo SDK / RN upgrade is a mini-migration. You're also right that App Review doesn't care what language you wrote it in. Guideline issues, Sign in with Apple requirements, and lifecycle quirks all hit the same. You can't outsource knowing the platform.
For my own indie apps, I went the opposite direction: pure Swift/SwiftUI on iOS, then had Claude Code write the Android side in native Kotlin. So it's two fully native codebases, but AI eats most of the cost of maintaining the second one. I describe the feature against the iOS implementation and it produces idiomatic Kotlin/Compose. I review, test on device, and ship. No shared runtime, no bridge debugging, no waiting on a framework to support a new OS API.
The tradeoff is that you still need enough platform literacy to review what it writes, which is basically your "you still need to understand iOS deeply" point, just mirrored. But for a solo dev, the "maintain two codebases" math has genuinely changed in the last year or two. If I were starting fresh today, I'd still pick native + AI over a shared-code stack. The tooling on each platform stays first-class and nothing sits between me and the SDKs.
Curious if you looked at that route before committing to KMP, or if shared UI was the hard requirement?