https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
o

Orhan Tozan

12/26/2019, 11:54 PM
Hey guys, we are using Kotlin to build a native Android app, and we are planning to also build an native iOS app. We have a lot of business logic written in Kotlin right now, and its nicely layered, so seperated from the Android framework. I've read about Kotlin Multiplatform and its option to share common logic between different platforms, although after reading more, I'm not sure if our usecase is supported by Kotlin multiplatform. My question and usecase is: is it possible to have a 3 seperate repo setup: core (written in Kotlin), android-app (written in Kotlin) and ios-app (written in Swift). android-app and ios-app both use the core project. So that means that the Core module/repo doesn't know anything about the android/ios project.
k

kpgalligan

12/27/2019, 12:02 AM
I would say that’s the primary use case of Kotlin Multiplatform. So, yes, supported.
o

Orhan Tozan

12/27/2019, 12:06 AM
@kpgalligan thanks for the response. The reason why I thought it wasn't possible, is because I came across this post saying its not supported right now: https://discuss.kotlinlang.org/t/common-only-multiplatform-project/12904
Could you elaborate the difference between my use case, and the use case described in the post concluded to be not supported?
Do you know if it is related to this issue: https://youtrack.jetbrains.com/issue/KT-30088 ?
k

kpgalligan

12/27/2019, 12:09 AM
I would completely ignore that thread. There seems to be mutual misunderstanding of multiplatform going on there.
You can’t import a “common” dependency into a “native” target, but from the context, I don’t think anybody involved in that thread had a clear grasp of the subject matter.
You can create common code in Kotlin, and generate a framework that you can call from iOS (Swift or Objc), and call the same code from Android. You do need to make sure any code you write or dependencies you use will be compatible.
So, summary. What you want to do is supported. Pretend that thread doesn’t exist.
o

Orhan Tozan

12/27/2019, 12:21 AM
Thanks for the clarification. I am reading the tutorial for setting up a MPP with Android and iOS, but the tutorial seems to put the shared, android and ios code all in the same repo/directory. The Shared module also contains a build.gradle file that seems to have iOS and Android related code, although the idea in my use case was that the "core" code of the whole domain didn't know anything about Android / iOS https://github.com/kotlin-hands-on/mpp-ios-android/blob/master/SharedCode/build.gradle.kts
d

Dico

12/27/2019, 2:21 AM
What you can do is have a common multiplatform project in one repo with targets for all your dependents (ios, android probably). You will have an ios and android sourceset for any platform-specific code that your common code depends on (if any). You can then use the multiplatform project as a dependency in all other projects with specific targets.
👍 1
So common code depends on platform-specific code, and then other platform-specific code can use the common code.
👍 1
o

Orhan Tozan

12/27/2019, 12:35 PM
@Dico thanks, this really helps. If I don't have any platform-specific code, can I omit the android and iOS sourceset? (so that the multi platform project don't have any mentions of iOS.
🚫 1
s

Sam

12/27/2019, 12:41 PM
No. Think of common projects like an abstract base class. It has to have a platform subclass to actually be used.
o

Orhan Tozan

12/27/2019, 12:42 PM
@Sam even for things like a data class?
d

Dico

12/27/2019, 12:42 PM
You need to have the targets specified, the source sets may be configured but don't need to be created or contain any files
o

Orhan Tozan

12/27/2019, 12:45 PM
So are you saying that, in contrast to what Sam is saying, a platform implementation/subclass of the common code is NOT needed?
s

Sam

12/27/2019, 12:50 PM
Sorry my analogy is confusing. I meant it at the project level. A common project has no meaning without a specific target. It can’t be built on its own. You need a platform target to actually compile the code to something.
o

Orhan Tozan

12/27/2019, 12:52 PM
What if there is a seperate iOS repo with pure swift code, and that just imports/calls the common module as a dependency. Does that count?
d

Dico

12/27/2019, 12:54 PM
There doesn't need to be any platform specific code. There just needs to be a compatible target configured so it can compile, as Sam pointed out
so
Copy code
kotlin {
    iosX64()
    android()
}
s

Sam

12/27/2019, 1:00 PM
The most common way for iOS (swift or objc) code to call Kotlin code is through a framework built in Kotlin. You have to build a binary. Even in Xcode when you have a project that has Swift and objc they are communicating through the objc protocol at runtime only. Xcode actually builds two separate binaries and includes them in your app bundle.
o

Orhan Tozan

12/27/2019, 1:25 PM
@Dico is that literally the only code required or is it just pseudo code?
d

Dico

12/27/2019, 1:25 PM
I urge you to look at examples from other projects (e.g. ktorio/ktor, touchlab/stately).
o

Orhan Tozan

12/27/2019, 1:26 PM
The difference is that those example all are in a single repo
d

Dico

12/27/2019, 1:27 PM
It is the same with extra platform-specific code
s

Sam

12/27/2019, 2:25 PM
You can do Android App Repo and an iOS app repo that both depend on a library repo. The library repo still has to define an iOS framework target an an Android aar or jvm jar target using the above gradle syntax.
d

Dmitri Sh

12/29/2019, 1:48 AM
Quoting: "So that means that the Core module/repo doesn't know anything about the android/ios project." Yes like other people said here, that's the essence of KMP. You start with the common (core as you call it), and platform specific actualize it (or just implement placeholders if there is nothing to do). Did a two month experiment with it, business logic is 100% nicely shareable.
d

Dico

12/29/2019, 12:15 PM
How do you establish apis like observable in common code?
o

Orhan Tozan

01/01/2020, 5:30 AM
Ok, just to be clear, Kotlin mo and native are two different things right. I can use mo without using kotlin native and write my iOS app in swift, so no performance tradeoffs are made.
2 Views