Kotlin multiplatform/native interoperability with Objective-C framework
I ended up with this cinterops
section in build.gradle
fromPreset(presets.iosX64, 'ios') {
// This preset is for iPhone emulator
// Switch here to presets.iosArm64 (or iosArm32) to build library for iPhone device
compilations.main {
outputKinds('FRAMEWORK')
cinterops {
firebase {
defFile "$projectDir/src/iosMain/cinterop/firebase.def"
includeDirs {
allHeaders "$projectDir/../iosApp/Pods/FirebaseCore/Firebase/Core/Public",
"$projectDir/../iosApp/Pods/FirebaseDatabase/Firebase/Database/Public"
}
compilerOpts "-F$projectDir/../iosApp/Pods/Firebase -F$projectDir/../iosApp/Pods/FirebaseCore -F$projectDir/../iosApp/Pods/FirebaseDatabase"
linkerOpts "-F$projectDir/../iosApp/Pods/Firebase -F$projectDir/../iosApp/Pods/FirebaseCore -F$projectDir/../iosApp/Pods/FirebaseDatabase"
}
}
}
}
end this .def
file:
language = Objective-C
headers = FirebaseCore.h FirebaseDatabase.h
What's going on here? Cocopods frameworks are placed in Pods
directory in your Xcode project. Navigating this folder a bit, you'll find what you need. I'm not sure if there is some standard but firebase place main header file in Public
folder. And it contains references to other header files it needs... So you specify these file names in your .def
file in the headers section.
Next, you need to specify where to look for these files and others referenced by them. You can do it in the .def
file in includeDirs
or in build.gradle
file. I prefer to use the build.gradle file as it can use variables. So you specify the path to these Public
folders. (This is enough for kotlin to see library API, but in order to be able to run the app you need to compile and link this library...)
Then the compiler and linker need to know where library/framework is. So you specify path to root folder of the framework in compilerOpts
and linkerOpts
prefixing them with -F
if it is a framework or -L
if it is a library.