#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
чтобы сделать это.