App Store (iOS)Kotlin

How to Publish a Kotlin App on the App Store

Kotlin Multiplatform (KMP) allows you to share business logic between Android and iOS while building native UIs with SwiftUI or UIKit. Publishing the iOS side requires integrating KMP's Kotlin/Native output into an Xcode project. This guide covers how to take your KMP shared module, wrap it in a proper iOS app, and submit it to the App Store.

Prerequisites

  • A Mac with Xcode 15+ installed
  • An Apple Developer Program membership ($99/year)
  • Kotlin Multiplatform project set up (shared + iosApp modules)
  • Android Studio with KMP plugin for editing shared code
  • CocoaPods or Swift Package Manager for iOS integration

Step-by-Step Build Process

1

Configure the iOS framework export

In your shared module's build.gradle.kts, configure the `ios()` target and framework export: `iosX64()`, `iosArm64()`, `iosSimulatorArm64()`. Set `baseName = "shared"` and configure export settings. Run `./gradlew linkReleaseFrameworkIosArm64` to build.

2

Integrate with the Xcode project

Use CocoaPods integration (`cocoapods { }` block in build.gradle.kts) or SPM. The KMP Gradle plugin can generate a podspec or xcframework. In the iosApp Xcode project, add the framework dependency.

3

Build the iOS app with SwiftUI/UIKit

Write iOS-native UI in the iosApp module using SwiftUI or UIKit. Import the shared framework and call your Kotlin business logic. Build and test on a simulator, then on a physical device.

4

Archive for distribution

Open the iosApp.xcworkspace in Xcode, select 'Any iOS Device', and create an archive via Product > Archive. Ensure the shared framework is properly embedded and signed.

Code Signing & Certificates

Sign the main app and framework

Both the main iosApp target and the embedded KMP framework need proper signing. Use automatic signing for the app target. The framework should be set to 'Embed & Sign' in the Frameworks, Libraries, and Embedded Content section.

Handle framework architectures

Build a universal (XCFramework) for distribution that includes arm64 for devices. Run `./gradlew assembleXCFramework` to create a multi-architecture framework compatible with both simulators and devices.

Store Submission Steps

1

Create the app in App Store Connect

Set up the app with matching bundle ID. KMP apps appear as fully native iOS apps to Apple — there's no special category or disclosure needed.

2

Upload and test with TestFlight

Upload the archive via Xcode Organizer. Test with TestFlight to verify KMP shared code works correctly in release mode — Kotlin/Native has different memory management behavior in release vs debug.

3

Complete metadata and submit

Fill in all App Store Connect fields, upload screenshots, and submit for review. KMP apps review like any native app — Apple can't tell the difference.

Common Rejection Reasons & Fixes

Crashes in release mode (Kotlin/Native memory)

Kotlin/Native uses a different memory manager in release builds. Test with release configuration before submitting. Common issues include shared mutable state and coroutine lifecycle problems. Enable the new Kotlin/Native memory manager.

Missing iOS-native feel

Don't force Android UI patterns into iOS. Use SwiftUI for the iOS UI layer and only share business logic through KMP. Navigation, gestures, and visual design should follow iOS conventions.

App size too large

KMP apps can be larger than pure Swift apps due to the Kotlin/Native runtime. Strip debug symbols, enable dead code elimination, and minimize the shared module's public API surface.

Privacy manifest requirements

Create a PrivacyInfo.xcprivacy file for your app. If your KMP shared code uses APIs that require privacy declarations (networking, storage), declare them in the manifest.

Pro Tips

  • Use Kotlin's expect/actual pattern for platform-specific implementations within shared code
  • Test release builds frequently — Kotlin/Native behaves differently in release vs debug
  • Keep the shared module focused on business logic — don't try to share UI code for iOS
  • Use SKIE (Swift-Kotlin Interface Enhancer) for better Swift interop with sealed classes and coroutines
  • Monitor binary size — Kotlin/Native runtime adds overhead compared to pure Swift

Skip the hassle. Let us handle it.

Publishing a Kotlin app on the App Store (iOS) involves dozens of steps, certificates, and potential rejection pitfalls. Our team handles the entire process for you — from build configuration to store approval.

Related Guides