是的,在跨平台项目中,可以使用Kotlin/Native在Kotlin和本机iOS UI代码之间传输数据.这允许基于Kotlin具有用于数据模型的公共代码库,同时例如继续使用用于iOS的本机UI代码.
原始证据:
项目https://github.com/justMaku/Kotlin-Native-with-Swift向我指出了正确的方向,因为它显示了这样做的基本步骤:
在Swift UIViewController中,它调用一个包装器函数,该函数将从Kotlin函数接收一个字符串.调用是通过C++层调解的,C++层本身启动Kotlin运行时,将请求传递给Kotlin函数,从中接收字符串,然后将其传递回Swift UIViewController,然后显示它.
在技术层面上,该项目包含一个脚本,该脚本将Kotlin,C++和Kotlin/Native部分编译为静态库,然后可以从本机iOS项目调用该库.
为了运行代码,我在运行"./setup.sh"之前(在从git克隆之后)执行"git子模块同步".
为了使用基于Kotlin的数据模型传输数据,我希望有一个通用函数,可以将数据传递给Kotlin,修改该数据,并将结果返回到本机iOS代码.作为原理的证明,可以构建这样的函数,我将项目扩展到不仅从Kotlin接收字符串,而且将一个字符串发送到Kotlin,附加它,并将结果发回.
项目延期:
由于在这个看似简单的扩展中存在一些障碍,我为任何感兴趣的人布置了步骤.如果您继续,则应显示以下内容:
文字可能很愚蠢,但它会告诉你,会发生什么.函数viewDidAppear中ViewController.swift的变化是:
let swiftMessage: String = "Hello Kotlin, this is Swift!"
let cStr = swiftMessage.cString(using: String.Encoding.utf8)
if let retVal = kotlin_wrapper(cStr) {
let string = String(cString: retVal)
...
}
Run Code Online (Sandbox Code Playgroud)
您可以看到Swift在包装函数中发送给Kotlin的文本(最后,将显示生成的'string'变量).可以直接将Swift String传递给包装器,但我想强调包装器会将输入和输出视为c-strings.实际上,本机iOS项目中的文件Kotlin Native-Bridging-Header.h现在变为:
extern const char* kotlin_wrapper(const char* swiftMessage);
Run Code Online (Sandbox Code Playgroud)
在它上面的文件Launcher.cpp.由于原始文件使用KString作为kotlin_main的结果值,我试了一段时间将const char*转换为KString并将其传递给kotlin_main.最后我发现,将const char*变量直接传递给Kotlin并使用Kotlin/Native给我们的函数进行转换要简单得多.
然后我的Launcher.cpp变得比原来更紧凑.这是完整的文件:
#include "Memory.h"
#include "Natives.h"
#include "Runtime.h"
#include "KString.h"
#include <stdlib.h>
#include <string>
extern "C" const char* kotlin_main(const char* swiftMessageChar);
extern "C" const char* kotlin_wrapper(const char* swiftMessageChar) {
RuntimeState* state = InitRuntime();
if (state == nullptr) {
return "Failed to initialize the kotlin runtime";
}
const char* exitMessage = kotlin_main(swiftMessageChar);
DeinitRuntime(state);
return exitMessage;
}
Run Code Online (Sandbox Code Playgroud)
您将看到包装器如何首先启动Kotlin运行时,然后调用函数kotlin_main,该函数位于文件kotlin.kt中:
import konan.internal.ExportForCppRuntime
import kotlinx.cinterop.CPointer
import kotlinx.cinterop.ByteVar
import kotlinx.cinterop.cstr
import kotlinx.cinterop.nativeHeap
import kotlinx.cinterop.toKString
@ExportForCppRuntime
fun kotlin_main(cPtr: CPointer<ByteVar>): CPointer<ByteVar> {
val swiftMessage = cPtr.toKString()
val kotlinMessage = "Hello Swift, I got your message: '$swiftMessage'."
val returnPtr = kotlinMessage.cstr.getPointer(nativeHeap)
return returnPtr
}
Run Code Online (Sandbox Code Playgroud)
指针转换为Kotlin字符串,然后用于创建kotlinMessage(数据转换的示例).然后将结果消息转换回指针,并通过包装器返回到Swift UIViewController.
然后去哪儿?
原则上,可以使用此框架而无需再次触及C++层.只需定义pack和unpack函数,将任意数据类型打包成字符串,然后将字符串解压缩到另一端的相应数据类型.这种打包和解包函数必须每种语言只写一次,如果做得足够通用,可以重复用于不同的项目.在实践中,我可能会首先重写上面的代码来传递二进制数据,然后编写pack和unpack函数来将任意数据类型转换为二进制数据.
| 归档时间: |
|
| 查看次数: |
980 次 |
| 最近记录: |