Hey there! If you're an Android developer eyeing the iOS world, you're in the same spot I was a couple of years ago. I spent over five years building indie apps with Kotlin, loving its clean syntax. But last year, I took the plunge into iOS with Swift, and it's been a wild ride. Not all smooth, but definitely worth it. In this post, I'll share my experience transitioning, focusing on coding differences, exploring Kotlin Multiplatform as a bridge, tackling Google Play's tough policies, and highlighting why iOS's App Store and revenue potential feel like a better deal for indie devs like me. I'll keep it friendly, human, and structured for clarity, with a handy table to break things down. 1. Coding Differences: Kotlin to Swift Diving into Swift from Kotlin was like learning a new dialect of a familiar language. Both are modern, type-safe, and null-aware, but the differences hit me right away. Here's what stood out: Null Safety: Kotlin's ? for nullable types and safe calls (?., ?:) are a breeze. Swift uses optionals (?) with if let or guard for unwrapping, and force-unwrapping (!) can crash if you're not careful. I ported a Kotlin data class (data class User(val name: String?, val age: Int)) to a Swift struct (struct User { let name: String?; let age: Int }). Swift's let for immutability forced me to plan data flow better, which cleaned up my code.Extensions: Kotlin's extension functions (like adding isValidEmail() to String) have a Swift counterpart in extensions. They're nearly identical, so this was an easy shift. But Swift's protocol-oriented programming was a game-changer. Unlike Kotlin's interfaces, Swift protocols with extensions let me write modular, reusable code, cutting boilerplate from my Android utils.Error Handling: Kotlin leans on try-catch for exceptions. Swift uses enums for errors (enum NetworkError: Error { case timeout, invalidURL }) and do-try-catch. It felt verbose at first, but it made error paths crystal clear. I rewrote a Kotlin API fetcher in Swift, and the explicitness saved me from bugs.UI and Concurrency: Jetpack Compose on Android is declarative, like SwiftUI on iOS. Transitioning from Compose modifiers to SwiftUI was smooth, but I missed Kotlin's coroutines. Swift's async/await and Actors took time to grasp, especially for concurrent API calls. My first SwiftUI feature (a profile screen) felt snappier than Compose after optimization. Null Safety: Kotlin's ? for nullable types and safe calls (?., ?:) are a breeze. Swift uses optionals (?) with if let or guard for unwrapping, and force-unwrapping (!) can crash if you're not careful. I ported a Kotlin data class (data class User(val name: String?, val age: Int)) to a Swift struct (struct User { let name: String?; let age: Int }). Swift's let for immutability forced me to plan data flow better, which cleaned up my code. Null Safety Extensions: Kotlin's extension functions (like adding isValidEmail() to String) have a Swift counterpart in extensions. They're nearly identical, so this was an easy shift. But Swift's protocol-oriented programming was a game-changer. Unlike Kotlin's interfaces, Swift protocols with extensions let me write modular, reusable code, cutting boilerplate from my Android utils. Extensions Error Handling: Kotlin leans on try-catch for exceptions. Swift uses enums for errors (enum NetworkError: Error { case timeout, invalidURL }) and do-try-catch. It felt verbose at first, but it made error paths crystal clear. I rewrote a Kotlin API fetcher in Swift, and the explicitness saved me from bugs. Error Handling UI and Concurrency: Jetpack Compose on Android is declarative, like SwiftUI on iOS. Transitioning from Compose modifiers to SwiftUI was smooth, but I missed Kotlin's coroutines. Swift's async/await and Actors took time to grasp, especially for concurrent API calls. My first SwiftUI feature (a profile screen) felt snappier than Compose after optimization. UI and Concurrency It took me about three months to feel confident. I leaned on Apple's Swift tutorials and Kodeco for learning. Tip: Port a small Android feature to SwiftUI to spot patterns, like how Kotlin's sealed classes map to Swift enums with associated values. 2. Kotlin Multiplatform: A Hybrid Path Before going full iOS, I tried Kotlin Multiplatform (KMP) to share code between Android and iOS. It was a lifesaver! KMP lets you write shared logic (data models, networking) in Kotlin, compiling for both platforms. I took my Android app's Retrofit-based networking layer and made it multiplatform. Using expect/actual for platform-specific bits (Ktor with Darwin for iOS), I shared 60% of my logic, saving weeks of work. Pros: Less code duplication, faster iterations, and staying in Kotlin's comfort zone. Cons: Compose Multiplatform for UI is still young, and iOS performance lagged behind SwiftUI in my tests. Debugging cross-platform bugs (like an iOS date parsing issue) was a headache. If you're an indie dev with limited time, KMP is a great way to test iOS without a full rewrite. Check JetBrains' KMP docs or Android's codelab to start. 3. Google Play Policies: A Struggle for Indie Devs Google Play's policies have become a pain for indie devs. The closed testing rule hit me hard: new personal accounts (post-November 2023) need 20 testers for 14 days before going live. I scrambled to find testers, which is tough for solo devs. Account terminations are scarier. I've seen peers lose years of work over vague violations (e.g., "repetitive content"). One friend got banned for a minor ad issue, with no clear appeal process. It's nerve-wracking when your app is your livelihood. Apple's App Store, while strict, feels fairer. No tester quotas for small apps, and terminations seem less frequent for legit devs. Reviews take longer (1-2 weeks vs. Play's hours), but human reviewers catch things like UI glitches and give actionable feedback. Apple's focus on quality reduces spam, helping indie apps stand out. 4. Revenue: Why iOS Wins for Indies Money talks, and iOS delivers. In 2024, the App Store earned $103 billion vs. Google Play's $47 billion. My Android apps made okay ad revenue, but iOS users spend more on in-app purchases and subscriptions. After porting one app, my monthly earnings doubled in six months. Android's device fragmentation means more testing, eating into profits, while iOS's controlled ecosystem lets you focus on features. Apple's 30% cut matches Play's, but higher user spending makes up for it. AspectAndroid (Kotlin)iOS (Swift)Kotlin MultiplatformLanguage Features Nullable types, coroutines, extensions Optionals, async/await, protocols Shared Kotlin logic, platform-specific code UI Framework Jetpack Compose (declarative) SwiftUI (declarative) Compose Multiplatform (maturing) Store Policies 20-tester rule, frequent bans Strict but fair, no tester quotas Same policies apply to final apps Revenue Potential $47B (2024), ad-heavy $103B (2024), strong in-app purchases Depends on target platform Learning Curve Familiar for Android devs 2-3 months to adapt Moderate, leverages Kotlin skills Add RowRemove RowAdd ColRemove Col AspectAndroid (Kotlin)iOS (Swift)Kotlin MultiplatformLanguage Features Nullable types, coroutines, extensions Optionals, async/await, protocols Shared Kotlin logic, platform-specific code UI Framework Jetpack Compose (declarative) SwiftUI (declarative) Compose Multiplatform (maturing) Store Policies 20-tester rule, frequent bans Strict but fair, no tester quotas Same policies apply to final apps Revenue Potential $47B (2024), ad-heavy $103B (2024), strong in-app purchases Depends on target platform Learning Curve Familiar for Android devs 2-3 months to adapt Moderate, leverages Kotlin skills AspectAndroid (Kotlin)iOS (Swift)Kotlin MultiplatformLanguage Features Nullable types, coroutines, extensions Optionals, async/await, protocols Shared Kotlin logic, platform-specific code UI Framework Jetpack Compose (declarative) SwiftUI (declarative) Compose Multiplatform (maturing) Store Policies 20-tester rule, frequent bans Strict but fair, no tester quotas Same policies apply to final apps Revenue Potential $47B (2024), ad-heavy $103B (2024), strong in-app purchases Depends on target platform Learning Curve Familiar for Android devs 2-3 months to adapt Moderate, leverages Kotlin skills AspectAndroid (Kotlin)iOS (Swift)Kotlin Multiplatform Aspect Android (Kotlin) iOS (Swift) Kotlin Multiplatform Language Features Nullable types, coroutines, extensions Optionals, async/await, protocols Shared Kotlin logic, platform-specific code Language Features Nullable types, coroutines, extensions Optionals, async/await, protocols Shared Kotlin logic, platform-specific code UI Framework Jetpack Compose (declarative) SwiftUI (declarative) Compose Multiplatform (maturing) UI Framework Jetpack Compose (declarative) SwiftUI (declarative) Compose Multiplatform (maturing) Store Policies 20-tester rule, frequent bans Strict but fair, no tester quotas Same policies apply to final apps Store Policies 20-tester rule, frequent bans Strict but fair, no tester quotas Same policies apply to final apps Revenue Potential $47B (2024), ad-heavy $103B (2024), strong in-app purchases Depends on target platform Revenue Potential $47B (2024), ad-heavy $103B (2024), strong in-app purchases Depends on target platform Learning Curve Familiar for Android devs 2-3 months to adapt Moderate, leverages Kotlin skills Learning Curve Familiar for Android devs 2-3 months to adapt Moderate, leverages Kotlin skills Add RowRemove RowAdd ColRemove Col Add Row Remove Row Add Col Remove Col FAQs Q: How long does it take to learn Swift as a Kotlin developer? Q: How long does it take to learn Swift as a Kotlin developer? A: For me, it took about three months to feel comfortable. The syntax is similar, but SwiftUI and Xcode took time. Start with Apple’s Swift tutorials and build a small app to practice. Q: Is Kotlin Multiplatform a full replacement for native iOS development? Q: Is Kotlin Multiplatform a full replacement for native iOS development? A: Not quite. KMP is great for sharing logic (I shared 60% of my code), but UI via Compose Multiplatform isn’t as polished as SwiftUI yet. It’s best for hybrid projects or testing iOS. Q: How do I handle Google Play’s 20-tester rule as an indie dev? Q: How do I handle Google Play’s 20-tester rule as an indie dev? A: It’s tough! I asked friends, family, and online communities to test. Consider beta platforms like TestFlight for iOS, which has no such rule. Q: Are Apple’s App Store reviews really stricter than Google Play’s? Q: Are Apple’s App Store reviews really stricter than Google Play’s? A: Yes, but in a good way. Apple’s human reviews catch UI/UX issues and give feedback, while Play’s automated checks can feel random. Plan for longer review times on iOS. Q: Why is iOS revenue higher for indie devs? Q: Why is iOS revenue higher for indie devs? A: iOS users spend more on in-app purchases and subscriptions. My app’s earnings doubled on iOS, and the App Store’s $103B revenue (2024) vs. Play’s $47B shows the gap. Final Thoughts Switching to iOS stretched my skills but paid off big time. KMP helped ease the transition, Apple's policies feel less hostile, and the revenue boost sealed the deal. If you're curious, start with a small Swift project or KMP module. It’s opened new doors for me, and I bet it can for you too. Have you made the switch? Share your thoughts I’d love to hear! Happy coding!