Kotlin/Native iOS
1. Configuring K/N Project on Android Studio with Gradle
Latest Update 🎉
- 1st, Mar, 2019
- Kotlin 1.3.21
- Gradle 5.1.1
- Android Studio 3.3
Project Configuration
First, start with configuring K/N project on Android Studio, ver 3.3 .
Click Start a new Android Studio project
, select Empty Acticity
.
Next, input
- Application name, here
KotlinNativeiOS
- Package name
- Save location
- Language
Kotlin
- Minimum API level, here API 28, but anything is ok.
Finished with the above setting.
The KotlinNativeiOS
project will be opened automatically and gradle sync is performed. After that, you’ll see like the above image on left bar.
To setup directory, switch this Android
tab to Project
tab.
There are some directories and files. Like,
- .gradle/
- .idea/
- app/
- gradle/
- build.gradle
- etc..
Let’s take a look some files.
In build.gradle
, ext.kotlin_version = '1.3.20'
is written in buildscript
. This shows we are using Kotlin version 1.3.20 apparently. Now, Kotlin version 1.3.21 is available. We use it, so replace the variable if needed.
In gradle/wrapper/gradle-wrapper.properties
, distributionUrl
is defined. In my case, gradle-4.10-1-all.zip
are set. I changed to the following.
Then, Sync Now
button appears on top. Tap it and gradle sync will start.
Creating the Shared Module
This section’s goal is to create an iOS framework from Kotlin codes.
Right click on KotlinNativeiOS directory. And select New -> Directory.
Input sharedNative
(or any name you like). This directory will become shared module.
In the same way, create sharedNative/src/commonMain/kotlin
directories.
And create common.kt
file in kotlin
directory. We define helloWorld
function here as below.
package org.kotlin.mpp.mobilefun helloWorld() {
println("Hello World!")
}
We want to call this function from Swift. Let’s update the Gradle scripts.
First, we need to add the new project into the settings.gradle
, simply adding the following line to the end.
include ':sharedNative'
Next, create the sharedNative/build.gradle
.
After that, write the following codes.
apply plugin: 'kotlin-multiplatform'buildscript {
ext.ios_framework_name = 'KotlinShared'
}kotlin {
targets {
fromPreset(presets.iosX64, 'ios') {
binaries {
framework("$ios_framework_name") {
embedBitcode('disable')
}
}
}
}
sourceSets {
commonMain.dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
}
This is a gradle script for using kotlin multiplatform. The presets is iosX64
, for ios simulator, here. If you want to build for ios device, change this presets to iosArm64
. Defining the following variable may be helpful.
final def iosTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
? presets.iosArm64 : presets.iosX64
But, it’s ok. Go forward with presets.iosX64. You need Sync Now
here.
We will create the framework.
Open terminal and move to KotlinNativeiOS root directory, or use Android Studio’s Terminal.
We are here. Next, run the following command.
./gradlew :sharedNative:build
gradlew command can run :Module
‘s :task
. The above will perform building sharedNative module.
We found debug and release directories in sharedNative/build/bin/ios
directory. Each has .framework
in it. Frameworks are created 🎉.
ext.ios_framework_name = 'KotlinShared'
We defined an above variable in build.gradle and set it to framework("$ios_framework_name")
. The default name is main.framework
without it.
You see .dSYM in same directory. Crashlytics or other services uses this debug symbol file to symbolicate crash logs. But it appears only for debug. For release, this issue is reported.
There is one more block you need. This is the task to pack a framework to Xcode. It’s not good for your Xcode project to directly refer to the framework in above debug or release directory because it has build configuration DEBUG
or RELEASE
. The framework reference should be changed depending on it.
The following task is for that. Define this task in sharedNative/build.gradle
.
In the same way, Sync Now
and run this task.
Or, click this button for Gradle Sync
.
./gradlew :sharedNative:packForXcode
This command performs the sharedNative
module’s packForXcode
task defined above.
Finally, xcode-frameworks
directory and the framework appears. Xcode will refer this framework. Kotlin tutorials are a great way to learn more about Kotlin for Android beginners.
Hello World in Xcode
In this section, we call sharedNative framework’s helloWorld() function. But, it’s not so difficult. Simply, it is just a function of framework. It does not matter whether it is generated from Kotlin here.
So, I’d like to introduce some tips.
- relative path is good for
xcode-frameworks
from Xcode project. packForXcode
beforeCompile Sources
in build phase.
relative path
First, create KotlinNativeiOS/ios
directory and Xcode project with this configuration in it.
- Single View Application
- Product Name: SampleiOS
- Language: Swift
Like above, .xcodeproj
path is relative to sharedNative directory (framework in it). The path is $SRCROOT/../../sharedNative
. Using relative path, we can configure Xcode settings with environment variables.
K/N generates dynamic framework, so embed it to binaries.
Move to Xcode project’s General
tab. In Embedded Binaries
section, tap +
and click Add Other...
.
Choose the framework in xcode-frameworks
directory.
Create references.
Finished embedding.
Now we need to add this path to Framework Search Path
. Here, I use xcconfig file. Right click on SampleiOS group and choose Configuration Settings File
Config.xcconfig
was created. Set the path.
FRAMEWORK_SEARCH_PATHS = $(inherited) $SRCROOT/../../sharedNative/build/xcode-frameworks
Tell your project which configuration file is used. If you have already set framework search path directly in Build Settings, replacing it to $(inherited) will reflect the xcconfig file’s setting.
Now we can use sharedNative framework. In ViewController.swift,
🎉 🎉 🎉
packForXcode
before Compile Sources
in build phase
As I mentioned above, packForXcode
is the gradle task to exchange the framework to the one built in proper configuration, DEBUG
or RELEASE
.
It should be run before compiling sources.
In Build Phases, add new run script phase. It is generated as Run Script. I renamed it to Kotlin/Native. The script is the following.
cd $SRCROOT/../../sharedNative/build/xcode-frameworks./gradlew :sharedNative:packForXCode -PXCODE_CONFIGURATION=${CONFIGURATION}
Move the phase previous to the Compile Sources phase by dragging.
Check you can build successfully.
Summary
I explained how to configure Kotlin/Native project, setting up by Android Studio, building by Gradle, using framework in Xcode.
Now, you can convert Kotlin codes to Swift (strictly Objective-C). So try anything what you want to do, like using coroutines.
I have other articles mainly focused on practically using.
- Creating Simple Framework with Describing Some K/N Features.
- Coroutines and Immutability of K/N.
- Sample with K/N + Reactive Programming + Architectures. (coming soon)