Как использовать реализацию интерфейса по умолчанию с kotlin Multiplatform и Swift

#swift #interface #swift-protocols #kotlin-multiplatform #default-method

#swift #интерфейс #swift-протоколы #kotlin-мультиплатформенный #метод по умолчанию

Вопрос:

Я использую KMP для создания кроссплатформенного приложения как на Android, так и на iOS. Моя проблема в том, что когда я создаю интерфейс в Kotlin common main с реализацией по умолчанию, я не могу использовать эту реализацию в iOS, и мне нужно переписать код в Xcode. В моих методах нет ничего специфичного для платформы. Это просто функции, которые работают с числами (так, просто некоторые для или если с возвращаемым числовым параметром), поэтому для меня было бы очень полезно написать методы только один раз. Есть способ добиться этого?

Это интерфейс в 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 amp;amp; 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.

Спасибо.

Комментарии:

1. Спасибо, я добавил код. Я не писал это, потому что мой вопрос: как использовать реализацию метода по умолчанию (написанную в Android Studio с Kotlin) в Xcode в целом 🙂 Я приношу извинения за ошибку.

2. Интерфейс Kotlin сопоставляется с протоколом в ObjC. Это означает, что у него не может быть реализации по умолчанию. Вам нужно изменить это на class из interface и использовать composition при использовании этого класса.

3. Спасибо за ответ. Для решения проблемы я реализовал интерфейс в Android Studio, и в том же файле я создал класс, который реализует мой интерфейс, таким образом, в Xcode, чтобы я мог создать экземпляр объекта этого класса для использования методов по умолчанию. Может быть правильным решением?

Ответ №1:

Для решения проблемы я реализовал интерфейс в Android Studio, и в том же файле я создал класс, который реализует мой интерфейс, поэтому в Xcode я могу создать экземпляр объекта этого класса для использования методов по умолчанию.

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

Комментарии:

1. Это было полезно — спасибо! В моем случае я также хотел расширить класс в Xcode некоторыми специфичными для Swift деталями реализации для одного метода, и для этого мне нужно было пометить общий класс ( StandardValuesImplementation в вашем примере), open class чтобы сделать это.