Как читать массив объектов, сгенерированных в библиотеке фреймворка Swift, в общем модуле KMM (собственный kotlin)

Я работаю над приложением KMM. У общего модуля есть вспомогательный класс, который полагается на разные собственные библиотеки для части Android и части iOS. Это реализовано с помощью уже известного ожидаемого / фактического шаблона.

Как уже говорилось, фактический класс iOS использует платформу iOS, которая выполняет некоторые вычисления и возвращает массив объектов. Фреймворк ios, формирующий список объектов, работает корректно (тестировался с помощью модульных тестов). Ниже приводится упрощенный пример.

Это класс объектов, находящихся внутри массива:

public class ChildNodeIos:  NSObject{

public  let content:String
public let isTextNode:Bool

public init(content:String,isTextNode:Bool=false){
    self.content=content
    self.isTextNode=isTextNode
}

}

Вспомогательный класс на стороне iOS, который возвращает список объектов, будет примерно таким:

@objc public class IOSCoolHelper: NSObject {
    @objc public func getChildNodes(message: String) -> [ChildNodeIos]  {
       //build the array of child nodes here and return them
     }
}

В общем модуле kotlin внутри ожидаемого класса iOS функция вызывается следующим образом:

@Serializable
data class ChildNodeKN(val content :String,val isTextNode :Boolean=false)

import com.mydomain.iosframeworks.IosCoolHelper
actual class CoolHelper actual constructor(private val someStuff: String)  : ICoolHelper {

       actual override fun getChildNodes(message: String): List<ChildNodeKN> {
            val iosHelper= IOSCoolHelper()
            val swiftarray:List<ChildNodeIos>  = iosHelper.getChildNodes(message)
    
            //I was expecting to do something like that but it does not work (the content of "array is always empty"):
    
            val kotlinList:List<ChildNodeKN> = swiftarray as List<ChildNodeIos>
    
         return kotlinList
    }
        }
    
    }

Или, может быть, если список быстрых объектов не может быть напрямую приведен в эквивалентный список объектов kotlin, я ожидал, что смогу перебрать быстрый список и преобразовать его в список kotlin, что-то вроде этого:

    val kotlinList=mutableListOf<ChildNodeKN>()
swiftArray.foreach{
kotlinList.add(ChildNodeKN(it.content,it.isTextNode))
}

Но опять же, содержимое быстрого массива пусто. Выполнив множество тестов (я не могу их воспроизвести сейчас), мне удалось получить доступ к чему-то внутри массива, но это не был объект типа ChildNodeIos, и я не мог прочитать что-то на стороне kotlin.

Итак, вопрос в том, как получить на стороне kotlin список с более-менее сложными объектами внутри, который был сгенерирован на стороне iOS?

Я должен сказать, что у этого быстрого вспомогательного класса есть много других функций, которые возвращают примитивные значения (строки, логические значения или int), и это работает очень хорошо.

Я полагаю, что обходным путем будет вместо этого массив с объектами, чтобы вернуть массив с примитивными типами и двумя измерениями со стороны Swift, но я хотел бы работать с массивом объектов, если это возможно.

Спасибо за помощь


person R. Campos    schedule 12.03.2021    source источник


Ответы (1)


Мне удалось найти решение самостоятельно. Проблема заключалась в объявлении класса Swift объекта, содержащегося в списке. Я забыл объявление @objc для свойств класса, потому что в этом случае я не смог бы прочитать объекты внутри возвращенного массива.

открытый класс ChildNodeIos: NSObject {

@objc  public  let content:String
@objc  public let isTextNode:Bool

public init(content:String,isTextNode:Bool=false){
    self.content=content
    self.isTextNode=isTextNode
}

}

И затем, на стороне Kotlin, мне не удалось преобразовать его напрямую в список, но с помощью цикла foreach очень легко записать объекты iOS в объекты Kotlin:

person R. Campos    schedule 12.03.2021