swiftinterfaceswift-protocolskotlin-multiplatformdefault-method

How to use default interface implementation with kotlin Multiplatform and Swift


I'm using KMP to make a crossplatform app both on Android and iOS. My problem is that when I create an interface in Kotlin common main with a default implementation, I can't use that implementation in iOS and I need to rewrite the code in Xcode. Inside my methods there is nothing platform-specific. They are just functions that work with numbers (so, just some for or if with a return numeric parameter) so could very good for me write the methods just one time. There is a way to achive this?

This is the interface in Kotlin with the method and default implementation:

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)
}

This is an example of use in Android:

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

In 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
...
}

Otherwise I think that i will implements the interface in Kotlin and I will create a protocol with an extension in Swift.

Thanks.


Solution

  • To resolve I have implemented the interface in Android Studio and in the same file I have created a class that implement my interface so in Xcode I can instantiate an object of that class to use the default methods.

    Android Studio:

    interface StandardValues { 
    ... //default methods 
    } 
    
    class StandardValuesImplementation: StandardValues{} 
    

    Xcode:

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