Мультиплатформенная / нативная совместимость Kotlin с Objective-C framework
Я пытаюсь вызвать код Swift/Objective-C из Kotlin в мультиплатформенном проекте. Нет проблем с обращениями к коду платформы. Но когда я пытаюсь вызвать какую-то библиотеку (или фреймворк, не уверенный, как она правильно называется, так как я не разработчик iOS), это терпит неудачу. Документы утверждают, что можно вызвать код Objective-C и Swift, если он правильно экспортирован:
Kotlin / Native обеспечивает двунаправленную совместимость с Objective-C. Фреймворки и библиотеки Objective-C можно использовать в коде Kotlin, если они правильно импортированы в сборку (системные фреймы импортируются по умолчанию). Смотрите, например, "Использование cinterop" в документации плагина Gradle. Библиотека Swift может использоваться в коде Kotlin, если ее API экспортируется в Objective-C с помощью @objc. Модули Pure Swift пока не поддерживаются.
Но это ничего не говорит о том, как я могу импортировать их должным образом. Это только указывает на описание плагина gradle, которое описывает старую версию плагина gradle. Так что это не работает для меня. Наконец, я понял, что может быть способ импортировать код Objective C:
fromPreset(presets.iosX64, 'ios') {
compilations.main.outputKinds('FRAMEWORK')
compilations.main {
cinterops {
firebase {
def pods = '${System.getProperty("user.home")}/Projects/kmpp/iosApp/Pods/'
includeDirs '${pods}Firebase/CoreOnly/Sources',
'${pods}FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers'
}
}
}
}
Сборка работает без сбоев, но ничего не импортирует. Что я делаю неправильно? Можно ли вообще импортировать такую библиотеку?
UPD:
здесь я нашел пример использования cinterop
инструмент как это:
cd samples/gitchurn
../../dist/bin/cinterop -def src/main/c_interop/libgit2.def \
-compilerOpts -I/usr/local/include -o libgit2
Это выглядит как cinterop
инструмент должен быть в /dist/bin/
папка в моих проектах, но такой папки нет. Где взять cinterop
инструмент?
2 ответа
Я закончил с этим cinterops
раздел в 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"
}
}
}
}
конец это .def
файл:
language = Objective-C
headers = FirebaseCore.h FirebaseDatabase.h
Что тут происходит? Каркасы кокоподов размещены в Pods
каталог в вашем проекте xcode. Немного пройдясь по этой папке, вы найдете то, что вам нужно. Я не уверен, что есть какой-то стандарт, но Firebase разместить основной файл заголовка в Public
папка. и он содержит ссылки на другие заголовочные файлы, которые ему нужны... Таким образом, вы указываете имена этих файлов в вашем .def
файл в разделе заголовков.
Далее необходимо указать, где искать эти файлы и другие ссылки на них. Вы можете сделать это в .def
файл в includeDirs
или в build.gradle
файл. Я предпочитаю файл build.gradle, так как он может использовать переменные. Таким образом, вы указываете путь к этим Public
папки. (Этого достаточно для того, чтобы kotlin мог видеть API библиотеки, но чтобы запустить приложение, вам нужно скомпилировать и связать эту библиотеку...)
Компилятору и компоновщику нужно знать, где находится библиотека / фреймворк. Таким образом, вы указываете путь к корневой папке фреймворка в compilerOpts
а также linkerOpts
добавив к ним префикс -F
если это рамки или -L
если это библиотека.
Похоже, вы собираетесь использовать библиотеку cocoapods. В настоящее время плагин Gradle не поддерживает Cocapods из коробки. Но может быть зависимость от вашей библиотеки может быть настроена "вручную". Не могли бы вы поделиться ссылкой на ваш проект?