我正在开发一个支持 JVM、iOS 和 macOS 的 Kotlin/Native 多平台项目。我的设置有以下模块:
- common
- ios
- jvm
- macos
Run Code Online (Sandbox Code Playgroud)
我想使用一些本机代码作为actual类并将一个expected类放入common. 但是,对于多个目标(iOS 和 macOS),实际的类实现是相同的。有没有办法可以设置我的源代码(也许在 Gradle 中),这样我就不必维护实际类的 2 个相同副本?
我正在探索 Kotlin Native,并且有一个程序,其中有一群Workers执行并发操作(在 Windows 上运行,但这是一个普遍问题)。
现在,我想添加简单的日志记录。一个组件,它通过将字符串作为新行附加到以“附加”模式保持打开的文件中来简单地记录字符串。
(理想情况下,我只有一个“全局”功能......
fun log(text:String) {...} ]
Run Code Online (Sandbox Code Playgroud)
...我可以从任何地方打电话,包括从其他工作人员“内部”打电话,这会起作用。这里的含义是,由于 Kotlin Native 关于在线程之间传递对象的规则,执行此操作并不简单(TLDR:您不应该传递可变对象。请参阅: https: //github.com/JetBrains/kotlin-native/blob /master/CONCURRENCY.md#对象传输和冻结)。另外,我的日志函数理想地接受任何冻结的对象。)
我想出的是使用DetachedObjectGraph 的解决方案:
首先,我创建一个分离的记录器对象
val loggerGraph = DetachedObjectGraph { FileLogger("/foo/mylogfile.txt")}
Run Code Online (Sandbox Code Playgroud)
然后使用loggerGraph.asCPointer()(asCPointer())获取COpaquePointer分离图:
val myPointer = loggerGraph.asCPointer()
Run Code Online (Sandbox Code Playgroud)
现在我可以将此指针传递给工作人员(通过工作人员的执行函数的生产者 lambda),并在那里使用它。或者我可以将指针存储在@ThreadLocal全局变量中。
对于写入文件的代码,每当我想要记录一行时,我都必须DetachedObjectGraph再次从指针创建一个对象,attach()以便获取对我的 fileLogger 对象的引用:
val fileLogger = DetachedObjectGraph(myPointer).attach()
Run Code Online (Sandbox Code Playgroud)
现在我可以在记录器上调用日志函数:
fileLogger.log("My log message")
Run Code Online (Sandbox Code Playgroud)
这就是我在查看 Kotlin Native 中可用于并发的 API(从 Kotlin 1.3.61 开始)时想到的,但我想知道更好的方法是什么(使用 Kotlin,而不是诉诸 C …
我们假设一个 KMP 项目设置为具有示例 iOS 应用程序,其中添加了 KMP 模块的输出框架作为依赖项。
我在 KMP 模块中有一个函数sampleFuncForStringArrayList(names: ArrayList<String>),可以打印计数、迭代和打印 ArrayList 项目。
当我从 iOS 示例应用程序调用此函数时,我收到索引越界异常,因为 NSMutableArray在 iOS 应用程序环境中count为2,而在 KMP 模块中作为 ArrayList 接收时count为24576 。
此问题仅发生在releaseFramework 中。debugFramework工作正常。
//Swift
let namesStringList = NSMutableArray(array: ["Alice", "Bob"])
print("NSMutableArray COUNT : \(namesStringList.count)")
Main().sampleFuncForStringArrayList(names: namesStringList)
//Kotlin
public class Main {
public fun sampleFuncForStringArrayList(names: ArrayList<String>){
println("names.isNullOrEmpty() ${names.isNullOrEmpty()}")
println("names.count ${names.count()}")
names.forEach {
println("Hello $it")
}
}
}
Run Code Online (Sandbox Code Playgroud)
预期输出
NSMutableArray COUNT : 2
names.isNullOrEmpty() false
names.count 2
Hello …Run Code Online (Sandbox Code Playgroud) 我正在开发一个 Kotlin 多平台项目。我正在尝试使用计时器和倒计时器,但我无法访问kotlin.concurrent.fixedRateTimer或import kotlin.concurrent.timer在commonMain模块中。
这是根build.gradle:
plugins {
kotlin("multiplatform")
id("com.android.library")
id("kotlin-android-extensions")
}
// ...
kotlin {
//...
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.4.10")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.4.10")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9")
//...
}
}
//...
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以在那里使用这些方法。如果没有,我如何在模块中编写计时器和倒计时器commonMain?
我尝试使用Coroutines来实现相同的功能但失败了,因为它们不精确:
fun doAfter(delay: Long, action: () -> (Unit)) = launch {
delay(delay)
action.invoke()
}
fun countdown(time: Long, tick: Long, onTick: () -> (Unit), onFinish: () -> (Unit)) = launch { …Run Code Online (Sandbox Code Playgroud) 我无法将通用模拟库 (mockk.io) 与 kotlin 多平台一起使用。在他们的网站上,它说要在 kotlin 多平台中使用 mockk,你只需要将这一行添加到你的 gradle 中。testImplementation "io.mockk:mockk-common:{version}"
我添加了它并且它正常构建,只有当我想使用它时它才会失败。给予
Unresolved reference: io
Unresolved reference: mockk
Run Code Online (Sandbox Code Playgroud)
我的 gradle 文件
kotlin {
val hostOs = System.getProperty("os.name")
val isMingwX64 = hostOs.startsWith("Windows")
val nativeTarget = when {
hostOs == "Mac OS X" -> macosX64("native")
hostOs == "Linux" -> linuxX64("native")
isMingwX64 -> mingwX64("native")
else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
}
nativeTarget.apply {
binaries {
executable {
entryPoint = "main"
}
}
}
sourceSets {
val nativeMain by …Run Code Online (Sandbox Code Playgroud) 我想知道如何在KMM上为SQLDelight编写单元测试。首先,我什至无法正确添加SQLDelight依赖项。
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
// SQLDelight tests
implementation("com.squareup.sqldelight:sqlite-driver:1.4.3")
}
}
Run Code Online (Sandbox Code Playgroud)
在我添加依赖项然后同步项目后,该项目甚至没有构建。有人可以告诉我这是否是添加 sqlite 驱动程序依赖项的正确方法?
任何帮助将不胜感激!
unit-testing sqldelight kotlin-multiplatform kotlin-multiplatform-mobile
我读过这些 SO 帖子1、2、3,它们也面临着类似的问题。.klib我正在尝试在我的 KMM Android 项目中使用 a 。Klib 是从library.hC 头文件构建的。这就是我所做的:
在 KMM 项目中使用以下 Gradle 块shared:
kotlin {
...
androidNativeArm64 { // target
compilations.getByName("main") {
val mylib by cinterops.creating {
defFile(project.file("mylib.def"))
packageName("c.mylib")
// Options to be passed to compiler by cinterop tool.
compilerOpts("-I/home/me/CLionProjects/mylib/")
// Directories for header search (an analogue of the -I<path> compiler option).
includeDirs.allHeaders("/home/me/CLionProjects/mylib/")
// A shortcut for includeDirs.allHeaders.
includeDirs("/home/me/CLionProjects/mylib/")
}
}
binaries { …Run Code Online (Sandbox Code Playgroud) gradle android-studio kotlin-native kotlin-multiplatform kmm
假设我有一个包,即共享包,与两个 KMM 项目共享:KMM 项目 A 和 KMM 项目 B。
因此,我们有共享包 -> KMM 项目 A 和共享包 -> KMM 项目 B。
现在我想在我的 iOS 应用程序中使用 KMM 项目 A 和 KMM 项目 B。这是如何运作的?共享包是否与两个框架捆绑在一起(即我两次包含相同的依赖项?)。此外,共享包是否需要是 KMM 项目才能允许 KMM 项目 A 和 B 生成相关的 iOS 框架?或者它可以是一个纯 Kotlin 项目吗?
这是一个图表,可以对我试图理解的情况提供更多解释。
我有一个 C++ 库,需要从 android 和 iOS 中使用,所以我的想法是创建一个多平台模块,该模块将包装该库以从两个实现中使用它。
另一方面,我看到了 kotlin 本机使用 C 代码的示例: https://theprogrammershangout.com/resources/kotlin/native/creating-c-bindings.md/
这也是 kotlin 文档中的一个: https://kotlinlang.org/docs/native-c-interop.html
是否可以实现 jvm 和 iOS 的互操作性?
昨天,我用 Android Studio Bumblebee 2021.1.1 更新了我的 Mac,希望它能解决我遇到的多平台问题。
下面是我的 Mac 和版本的一些屏幕截图,100% 清晰:
当我创建新的 KMM 应用程序项目时,出现错误。这些是步骤(我无法发布所有屏幕截图):基本上接受所有默认设置,然后是最后一步:
单击“新建项目”对话框中的“完成”后,Android Studio 立即在右下角显示错误:“项目未配置” 项目未配置错误
之后我看到这些错误(文本如下): Android Studio 构建窗口输出
'pod install' command failed with an exception: Cannot run program "pod" (in directory "/Users/johndoe/AndroidStudioProjects/MyApplication/iosApp"): error=2, No such file or directory
Possible reason: CocoaPods is not installed
Please check that CocoaPods v1.10 or above and cocoapods-generate plugin are installed.
To check CocoaPods version …Run Code Online (Sandbox Code Playgroud) kotlin ×7
gradle ×2
kmm ×2
kotlin-multiplatform-mobile ×2
cocoapods ×1
interop ×1
mockk ×1
podfile ×1
sqldelight ×1
swift ×1
unit-testing ×1