如何在 kotlin Multiplatform 和 Swift 中使用默认接口实现

Posted

技术标签:

【中文标题】如何在 kotlin Multiplatform 和 Swift 中使用默认接口实现【英文标题】:How to use default interface implementation with kotlin Multiplatform and Swift 【发布时间】:2021-01-19 10:53:03 【问题描述】:

我正在使用 KMP 在 androidios 上制作跨平台应用程序。我的问题是,当我在 Kotlin common main 中使用默认实现创建接口时,我无法在 iOS 中使用该实现,我需要在 Xcode 中重写代码。在我的方法中,没有特定于平台的内容。它们只是处理数字的函数(因此,只有一些 for 或 if 带有返回数字参数),所以对我来说只需编写一次方法就非常有用。有没有办法做到这一点?

这是 Kotlin 中带有方法和默认实现的接口:

interface StandardValues 
fun nextValue(valueToCompare: String, currentStandardSpinner: String, currentUnitSpinner: Int): Pair<String, Int> 

    var currentStandardArray = StandardValue.E12.valuesStandard
    var indexSpinner = currentUnitSpinner
    var valueConverted = 0.0f

    try
        valueConverted = valueToCompare.toFloat()
     catch (e: NumberFormatException)
        e.printStackTrace()
        println(e)
    

    if(valueToCompare.isNotEmpty())
        var previousValue: Float = 0.0f

        if(valueConverted <= 1 && currentUnitSpinner == 0)
            return Pair("0",0)
        
        if(valueConverted < 1) 
            for ((index, value) in currentStandardArray.withIndex())
                if ((valueConverted * 1000) > value)
                    previousValue = currentStandardArray[index]
                
            
            if(indexSpinner != 0)
                indexSpinner--
            
            return Pair(previousValue.toString(), indexSpinner)
        
        if(valueConverted <= currentStandardArray.first())
            if(indexSpinner == 0)
                return Pair(currentStandardArray.first().toString(), 0)
            
            previousValue = currentStandardArray.last()
            indexSpinner--
            return Pair(previousValue.toString(), indexSpinner)
        
        for ((index, value) in currentStandardArray.withIndex())
            if (valueConverted > value)
                previousValue = currentStandardArray[index]
            
        
        return Pair(previousValue.toString(), indexSpinner)
    
    return Pair(currentStandardArray.first().toString(), indexSpinner)

这是一个在Android中使用的例子:

class FindRealComponent: AppCompatActivity(), AdapterView.OnItemSelectedListener, StandardValues 
...
myTextView.text = nextValue("3", "pF", 0).first

在 Xcode 中:

class MeasureConverterViewController: UIViewController, StandardValues 
    
    func nextValue(valueToCompare: String, currentStandardSpinner: String, currentUnitSpinner: Int) -> (String, Int)  
        //I would like to avoid to write the same logic code

   
textView.text = nextValue(nextValue("3", "pF", 0).0
...

否则我认为我将在 Kotlin 中实现接口,并在 Swift 中创建一个带有扩展的协议。

谢谢。

【问题讨论】:

谢谢,我已经添加了代码。我没有写它,因为我的问题是:如何在 Xcode 中使用默认方法实现(使用 Kotlin 在 Android Studio 中编写):) 我为这个错误道歉。 Kotlin 接口映射到 ObjC 中的协议。这意味着它不能在那里有默认实现。您需要将其从接口更改为类,并在使用此类时使用组合。 感谢您的回复。为了解决这个问题,我在 Android Studio 中实现了接口,并在同一个文件中创建了一个实现我的接口的类,因此我可以在 Xcode 中实例化该类的对象以使用默认方法。可能是一个正确的解决方案? 【参考方案1】:

为了解决这个问题,我在 Android Studio 中实现了接口,并在同一个文件中创建了一个实现我的接口的类,因此在 Xcode 中我可以实例化该类的对象以使用默认方法。

Android 工作室:

interface StandardValues  
... //default methods 
 

class StandardValuesImplementation: StandardValues 

Xcode:

class MyViewController: UIViewController 
... 
override func viewDidLoad()  
super.viewDidLoad() 
... 
let myClassImpl = StandardValuesImplementation() 
let textView = MyClassImpl.myDefaultMethod 
...

【讨论】:

这很有帮助 - 谢谢!就我而言,我还想在 Xcode 中使用一种方法的一些特定于 Swift 的实现细节来扩展类,为了做到这一点,我需要将共享类(在您的示例中为 StandardValuesImplementation)标记为 open class 到这样做。

以上是关于如何在 kotlin Multiplatform 和 Swift 中使用默认接口实现的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Kotlin-Multiplatform 在 iOS 应用程序的后台线程中运行任务?

如何在 Kotlin Multiplatform(纯 kotlin)中进行延迟

Kotlin Multiplatform:如何在 iOS 的单元测试中模拟对象

Kotlin-Multiplatform 中的 CPointer

如何在 Android 和 JVM 目标之间共享 Java 代码(使用 Kotlin Multiplatform)?

如何在 kotlin Multiplatform 和 Swift 中使用默认接口实现