Kotlin Mutliplatform:将 Swift/Objc 代码映射到 iOSMain 模块中的 Kotlin?

Lor*_*der 2 android ios kotlin swift kotlin-multiplatform

我正在学习KMM。我现在正在 iOSMain 和 Android main 中设计一个通用的位置获取

我的问题是,我不知道在 iOSMain 中将 Swift 映射到 Kotlin

例如,

获取位置的 Swift 代码是

var locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
var currentLoc: CLLocation!
if(CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
CLLocationManager.authorizationStatus() == .authorizedAlways) {
   currentLoc = locationManager.location
   print(currentLoc.coordinate.latitude)
   print(currentLoc.coordinate.longitude)
} 
Run Code Online (Sandbox Code Playgroud)

Kotlin 端实现:

科特林

在上面的代码中:

  1. 如何在 Kotlin 代码中使用 Swift 的.authorizedWhenInUseand .authorizedAlways

  2. 并且 in currentLoc.coordinate.longitude、 thelongitudelatitude没有解决。为什么 ?

请帮我

Der*_*Lee 5

将 Swift (Objective-C) 映射到 Kotlin

\n
\n
    \n
  1. 如何在 Kotlin 代码中使用 Swift 的 .authorizedWhenInUse 和 .authorizedAlways ?
  2. \n
\n
\n

根据Kotlin 的互操作性文档,Kotlin/Native 提供与 Objective-C 的双向互操作性,而不是 Swift,所以我的第一个建议是参考 Apple 的 Objective-C 文档而不是 Swift 文档。

\n

如果您调出.authorizedWhenInUse 的 Swift 文档,你会发现你可以将语言切换到 Objective-C:

\n

authorizedWhenInUse Swift 参考文档

\n
\n

将其切换到Objective-C 文档以查看如何在 Objective-C 中引用它:

\n

authorizedWhenInUse Objective-C 参考文档

\n
\n

鉴于此,您应该能够使用kCLAuthorizationStatusAuthorizedWhenInUse在 Kotlin 代码中使用。

\n

引用 iOS 框架

\n

由于您已经有一些参考代码,因此您也可以简单地 Command+Click(或 Command+B)其中一个对象(例如,CLLocationManager),它应该打开已编译的 Kotlin 代码。

\n

您还可以手动从 Android Studio \xe2\x86\x92“外部库”的“项目”视图访问所有 iOS 框架,然后搜索您正在搜索的 iOS 框架。

\n

在此输入图像描述

\n

在这里,您可以深入研究框架来找到您正在寻找的内容。如果不知道等效的 Objective-C API,您只需搜索“authorizedWhenInUse”即可找到它:

\n

Kotlin CoreLocation 框架参考代码

\n

处理 C 结构

\n
\n
    \n
  1. currentLoc.coordinate.longitude ,经纬度未解析
  2. \n
\n
\n

这个就比较复杂了...

\n

location属性是类型CLLocationCoordinate2D,并且(重要的部分!)是它包含在CValue

\n
@kotlinx.cinterop.ExternalObjCClass public open class CLLocation : platform.darwin.NSObject, platform.Foundation.NSCopyingProtocol, platform.Foundation.NSSecureCodingProtocol {\n\n    ...\n\n    public final val coordinate: kotlinx.cinterop.CValue<platform.CoreLocation.CLLocationCoordinate2D> /* compiled code */\n\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,在 Objective-C 中,CLLocationCoordinate2D是一个 C 结构体

\n
typedef struct CLLocationCoordinate2D {\n    ...\n} CLLocationCoordinate2D;\n
Run Code Online (Sandbox Code Playgroud)\n

这里的 Kotlin 文档很薄,但它显示了可用于 CValue 的方法,包括该.useContents()方法

\n

CValue.useContents() 方法定义

\n

因此,您的代码可以编写如下(编译并确认其运行并在物理设备上生成一个位置):

\n
@kotlinx.cinterop.ExternalObjCClass public open class CLLocation : platform.darwin.NSObject, platform.Foundation.NSCopyingProtocol, platform.Foundation.NSSecureCodingProtocol {\n\n    ...\n\n    public final val coordinate: kotlinx.cinterop.CValue<platform.CoreLocation.CLLocationCoordinate2D> /* compiled code */\n\n
Run Code Online (Sandbox Code Playgroud)\n

[2022 年 9 月更新] \n如果您想深入挖掘,我还发表了一篇关于使用 Kotlin 和 KMM 的期望/实际编写 iOS 平台相关代码的博客文章:artandscienceofcoding.com/science/avoid-this-kmm-技术

\n