Is it possible to not have all the iOS (kotlin/Native) tasks (cinterop + cocoapods) run when I am developing the android app with a Kotlin Multiplatform Project imported?
Our current KMP project (SharedLibrary) structure is:
SharedLibrary
- build.gradle.kts
- settings.gradle.kts
- ...
- shared
- build.gradle.kts
- commonMain
- androidMain (android library target)
- ...
We have a separate Android Project (SomeApp) with the following settings to import our shared library.
// settings.gradle.kts
include ":shared"
project(":shared").projectDir = file("../SharedLibrary/shared")
The thing is... this is quite an annoying development pattern especially since the iOS artifacts (cinterop + cocoapods etc) get rebuilt every time there is a change even if I only care about the android library artifact.
Things I tried:
Is this an issue with our setup? Or are the tasks just dependent on each other and there is no way around it?
You can exclude iOS target from build like this:
kotlin {
android()
// kotlin.native.cocoapods.target property passed by cocoapods build from Xcode
val shouldBuildIos = project.findProperty("kotlin.native.cocoapods.target") != null
if (shouldBuildIos) {
ios()
cocoapods {
// ...
}
}
sourceSets {
// ...
if (shouldBuildIos) {
val iosMain by getting {
libDependencies(
"ktor.client.engine.ios",
)
}
}
}
}
But in this case you won't have any code suggestions in the IDE. Also be careful because your podspec will be removed in this case.
If you're only working on android part and an other dev is working on iOS one, you can create you own property in the local.properties, and make sure you won't push removing podspec file(or just ignore it)
But if you're a single dev it's not a good option. I have faced long cocoapods build time too, and decided to move it from the multiplatform module.
Each time I need it, I create an interface in the common code, and pass an instance implementing it or a "generator" function(if you don't wanna create an object unless it's needed) from iOS part.
in y iOS part it looks something like this:
featureProvider = FeatureProvider(
context: .init(
rootController: rootViewController,
application: application,
launchOptions: launchOptions
),
providerGenerator: { socialNetwork, context -> CredentialProvider in
switch socialNetwork {
case .facebook:
return FacebookProvider(context: context)
case .google:
return GoogleProvider(context: context)
default: fatalError()
}
}
)