Integrating MLkit, anything I should be aware of? ...
# multiplatform
s
Integrating MLkit, anything I should be aware of? - iOS and Android are supported, so I guess I'd do
actual
/
expect
and have an `if`/`else` to handle the desktop, web &etc. targets?
b
You can use `expect`/`actual` or if you have DI in your project(I know that the next approach is possible with Koin) you can also write interface in your shared common source set and then write actual implementation of that interface directly in your targets source sets. I did the same thing in my project here. commonMain:
Copy code
import com.liftric.kvault.KVault
interface SecurePersistentStorageProvider {
    val kVault: KVault
}
iosMain:
Copy code
import com.liftric.kvault.KVault
class SecurePersistentStorageProviderImpl : SecurePersistentStorageProvider {
    override val kVault: KVault
        get() = KVault()
}
androidMain:
Copy code
import android.content.Context
import com.liftric.kvault.KVault
class SecurePersistentStorageProviderImpl(context: Context) : SecurePersistentStorageProvider {
    private val vault = KVault(context, "sp.bvantur.tasky.kvault")
    override val kVault: KVault
        get() = vault
}
Additional wrapper for Koin in iosMain:
Copy code
fun initKoinIos(
): KoinApplication = initKoin(module {
    singleOf(::SecurePersistentStorageProviderImpl).bind<SecurePersistentStorageProvider>()
})
And then you just provide the implementation for your interface directly in your native target projects with DI, in my example with Koin: Android native project:
Copy code
initKoin(
            targetModule = module {
                single<Context> { this@TaskyApplication }
            }
        )
iOS native project:
Copy code
KoinIOSKt.doInitKoinIos()
Just an alternative to
expect-actual
mechanism without strict need to cover an
actual
implementation in all targets.
But you need to be careful to not reach that code on other targets for which I think you would need
if-else
statements, yes. Or maybe there is a way to write one default implementation for other targets that is being used for non-supported targets and iOS and Android would still use the implementation in the way I wrote in my message above. That way you could also eliminate a need for
if-else
statements. Just an idea maybe worth exploring. ;)
s
Ohh just found https://kotlinlang.org/docs/native-cocoapods-dsl-reference.html#framework-block where I can do
Copy code
iosArm64.deploymentTarget = "13.5"
Hmm but that doesn't work, tried:
Copy code
iosX64()
iosX64.deploymentTarget = "13.5"

iosX64().deploymentTarget = "13.5"
Inside or outside the
kotlin { cocoapods
block, also tried in this block (also with/without
cocoapods
):
Copy code
listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }
        iosTarget.deploymentTarget = "13.5"
    }
Ok got that part working with this line inside `kotlin { cocoapods {`:
Copy code
ios.deploymentTarget = "13.5"
Currently trying to solve two issues:
Copy code
error: 'embedAndSign' task can't be used in a project with dependencies to pods.
and:
Copy code
Failed to generate cinterop for :composeApp:cinteropBarcodeScanningIosX64:
Failed to generate cinterop for :composeApp:cinteropBarcodeScanningIosArm64
# repeat for other architectures
Giving these errors:
Copy code
:composeApp:iosArm64Main: cinterop file: composeApp/build/classes/kotlin/iosArm64/main/cinterop/composeApp-cinterop-BarcodeScanning.klib does not exist
# repeat for other architectures
y
add pods like this
Copy code
pod("GoogleMLKit/BarcodeScanning") {
    moduleName = "MLKitBarcodeScanning"
    version = locallibs.versions.ios.google.barcode.scanning.get()
}
s
@Yuvaraj What is
locallibs
? - I had what you had but
"3.2.0"
there instead and that's what gave the errors. - Happy to try your solution, what's the trick? I also tried with a custom
Podfile
Any recommendations for how I can get Google MLKit barcode scanning working for iOS (Compose UI) in Kotlin?
y
@Samuel locallibs.versions.ios.google.barcode.scanning.get() is nothing it is just pulling the version from version.catalog and I use 6.0.0 version for MLKit
@Samuel I would suggest for ios you develop in swift package and open the scanner and return the result back to multiplatform through expect and actual. Writing in KotlinNative you will have to manage the Coroutines which don't work well with ios.
t
@Samuel updates? have you solved the issue?
s
No, iOS still doesn't work