This kickstarter gives our projects a flying start and ensures everything we’ve learned from earlier work can be easily reused in new projects.
Kickstarter for creating apps on Android and iOS.
We keep track of our wish list / issues at our GitHub Issues page.
- Install Android Studio
- check your system with KDoctor. Ignore Java not found warnings.
- add the Kotlin Multiplatform plugin to Android Studio
- in our IDE go to Setting > Advance Setting > enable "Experimental Multiplatform IDE Feature"
- If you want to refactor applicationId & all package naming use the script in
scripts/package_renaming.sh- Make sure to Gradle sync after running this script; Android Studio tends to get confused
To run the application on android device/emulator:
- open project in Android Studio and run imported android run configuration
To run the application on iPhone device/simulator:
- Make sure Xcode is installed
Use Kotlin Multiplatform Mobile plugin for Android Studio
- Play from Android Studio
Workflow: .github/workflows/android-ci-tests.yml
- runs on
pull_requestand pushes tomain - validates dependency licenses (
./gradlew licensee) - builds Android debug APK (
:androidApp:assembleDebug) - runs project checks (
./gradlew check, excluding iOS simulator tests) - uploads debug APK as a workflow artifact
Workflow: .github/workflows/android-cd-release.yml
- runs on
pushtodevelop - builds release APK and AAB (
:androidApp:assembleRelease+:androidApp:bundleRelease) - uploads release APK/AAB as workflow artifacts
Workflow: .github/workflows/ios-ci-tests.yml
- runs on
pull_requestandpush - validates Xcode/KMP configuration (
:shared:checkXcodeProjectConfiguration) - runs iOS simulator Kotlin tests (
:shared:iosSimulatorArm64Test) - builds iOS debug framework for simulator (
:shared:linkDebugFrameworkIosSimulatorArm64) - builds the iOS app for simulator via
xcodebuild
Workflow: .github/workflows/ios-cd-release.yml
- runs on
pushtodevelop - builds and code signs iOS app archives for all environments
- uploads debug symbols to Crashlytics
- uploads to TestFlight
Note: because the Kotlin Native framework is built using a 'run script' phase, the Xcode build setting ENABLE_USER_SCRIPT_SANDBOXING must remain set to NO.
Many of the architecture choices that were made are documented here: https://github.com/Q42/Template.Android
When data needs to be stored on disk, create a dedicated Entity model for the local layer.
Do not reuse domain or network models for persistence and do not add serialization/database annotations to those models just to make storage work.
The main data module uses a single DataStore instance for persistent preferences (for example app settings like onboarding states, theme, or language choices).
- Stored in
Library/Application Support/(NSApplicationSupportDirectory) - Included in standard iCloud backups to preserve user settings across devices
- Stored in
Context.filesDir(under thedatastore/subdirectory) - Included in the regular Auto Backup flow by default
The CI release workflows use version metadata from two different sources:
app.versionName: read fromgradle.propertiesand used as the semantic version label in release artifact names (for example1.0.0)github.run_number: provided by GitHub Actions via${{ github.run_number }}and used as the CI-drivenversion_codein workflow outputs
To change the visible release version label in CI artifacts, update app.versionName in gradle.properties. The CI run number is supplied automatically by GitHub Actions for each workflow run.
Before the iOS release workflow can succeed, review and adjust the following in .github/workflows/ios-release.yml for your project's specific needs:
- the
matrix.environmententry —app_identifier,firebase_plist,code_sign_entitlements, andscheme - the
envblock —XCODE_VERSIONandXCODE_PROJECT
The following environment variables must be configured in the repository's GitHub settings:
APPLE_DEVELOPER_TEAM_IDshould be set to your developer team ID. You can find this value at: https://developer.apple.com/account
The following environment secrets must be configured in the repository's GitHub settings:
IOS_CERTIFICATE_BASE64contains a base64-encoded string of the .p12 certificate bundle, used to code sign the app. This bundle should contain two certificates: development and distribution.IOS_CERTIFICATE_PASSWORDcontains the password of the certificate bundle.APP_STORE_CONNECT_API_KEY_BASE64contains a base64-encoded string of the .p8 App Store Connect API key.APP_STORE_CONNECT_API_KEY_IDcontains the key ID of the App Store Connect API key.APP_STORE_CONNECT_API_KEY_ISSUER_IDcontains the issuer ID of the App Store Connect API key.
To create a p12 a certificate bundle, open Keychain Access. Unfold the entries for the development and distribution certificate. Select the certificates and their private keys using shift, then right-click and select "Export 4 items...".
You can encode a file to base64 on the command line like this: base64 -i ~/Desktop/Certificates.p12 | pbcopy. This automatically puts the result on your clipboard.
Using the same base64 command, the App Store Connect API key can be encoded.
For CMP positional placeholders are required, so make sure to add strings properly in the string resource and add the position to the placeholder (e.g. %1$s instead of %s).
Check the link for more info: https://kotlinlang.org/docs/multiplatform/compose-multiplatform-resources-usage.html#plurals