Multiplatform Programming Using Kotlin Native — a mobile developer’s quest! — Part 3
We saw how a Kotlin Multiplatform app can be setup to work seamlessly on Android and iOS in the earlier post. Now, let’s take a look at the possible errors that you may encounter along the way and how to resolve them. Bam!
Troubleshooting Guide
Issue: 1
When you encounter this error and your build fails after a modification to your Kotlin code in the Android Studio or IntelliJ, then a couple of reasons for this are:
- You might be referring to the old SharedModule.framework file in Xcode.
- You did not run a gradle build or launch the Android Application after modifications performed to common.kt, iosMain/actual.kt or androidMain/actual.kt files
Solution:
- After making changes to the files in SharedModule, make sure you perform a “gradle build” in the terminal.
- And, launch the app once before opening Xcode with the KotlinIOS project
- Then head over to Xcode and open the KotlinIOS project and delete the SharedModule.framework if it’s already linked. And link it fresh by navigating to the build folder like below:
Select the “Move to Trash” option.
Then head over to the Project folder in your file system and add the new SharedModule.framework in the “Embedded Binaries” section in Xcode
Then build the project in Xcode. The error would be resolved by now.
Issue: 2
When you perform “./gradlew build” from the terminal when inside the project hierarchy for the first time, you may end up seeing errors like below.
If you encounter this issue, most probably, you have not configured Xcode Command line tools in Xcode preferences.
Solution:
Head over to your Xcode Preferences and update like the image below:
Also, if there are more than one version of Xcode installed, then execute command like below
Issue 3:
If you encounter the error like below:
Unable to find method ‘sun.misc.Unsafe.defineClass(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;’.
This is a gradle issue and asked me to restart or change my Java config as described in the link below:
Solution:
I upgraded the distributionUrl in gradle-wrapper.properties file with the updated value. Go for a Gradle version above 4.7
Issue 4:
ERROR: Cause: invalid type code: 68
This is a Gradle Sync issue.
Solution:
Do as below, disable the “only sync the active variant”
Issue 5:
In a new intellij project, if “gradlew” file is missing, you have to create one and it is done by adding the below snippet in build.gradle file of the project. And perform “sync now” or run “gradle wrapper” in the terminal.
https://stackoverflow.com/questions/29381954/gradlew-missing-in-generated-android-project
Solution:
taskwrapper(type:Wrapper) {gradleVersion=’<Your gradle version>’}
Issue 6:
There is an issue when launched and executed on intelliJ and there is a reported bug that is still open
https://youtrack.jetbrains.com/issue/KT-28559
This occurs when we tamper with the Java version. When the “SharedModule” is added as a Java Library, a build.gradle is generated with a default JDK value, like shown below:
Solution:
Let’s not change the Build Tools Version, Java Source and Target compatibility of App module in the project structure as shown below:
Issue 7:
If your system does not have gradle, install it from your terminal with the help of brew like below:
- brew install gradle
Then if there is no .bash_profile file, then steps to create one are below:
- touch .bash_profile
- Add the path to gradle like below:
- If you don’t know the path to gradle, then do
- brew info gradle
- If path that says “/usr/local/Cellar/gradle/5.4.1” appeared, now you know gradle is successfully installed
- A related link for reference is: https://stackoverflow.com/questions/44367082/gradle-home-cannot-be-found-on-mac
- And the path to be set in your .bash_profile is “/usr/local/opt/gradle/bin”
Summary
In the tutorial we:
- created an Android application in Android Studio
- created an iOS application in Xcode
- added Kotlin multiplatform sub-project
- with shared Kotlin code
- compiled it to Android Jar
- compiled it to iOS Framework
- put it all together and re-used Kotlin code
Future Direction
Sharing code between platforms is a powerful technique, but it may be hard to accomplish without rich APIs that we have in Android, JVM, or iOS platforms. Multiplatform libraries can be used to fix that. They bring rich APIs directly in the common Kotlin code. There are several examples of such libraries:
Addendum:
References:
https://kotlinlang.org/docs/tutorials/native/mpp-ios-android.html#creating-ios-application
Objective-C and Swift Interop — Kotlin Programming Language
https://kotlinlang.org/docs/reference/platform-specific-declarations.html
https://kotlinlang.org/docs/tutorials/native/apple-framework.html
russhwolf/multiplatform-settings: A Kotlin Multiplatform library for saving simple key-value data
Building your first Kotlin Multiplatform app — Getting Started
Kotlin/Native iOS — Quick Code — Medium
A practical Intro to Kotlin Multiplatform | Bugsnag Blog
Building a Kotlin Native on IOS/Android — Android Things — Medium
Please share your feedback and valuable comments. Also, feel free to reach out to me if you are having trouble setting up the project.
I have incorporated suggestions by few people, requesting me to split the post in parts. That’s been taken care of!
Thank you.