Я делаю проект Kotlin Multiplatform для Android и iOS. Моя цель состоит в том, чтобы выполнить сериализацию и сериализацию JSON в общем модуле и использовать эти данные на целевой платформе.
Но у меня есть проблема: он блокирует пользовательский интерфейс в приложении для iOS. Загрузка хороша, потому что она выполняется сетевой библиотекой, но когда JSON достаточно большой, а сериализация занимает некоторое время, пользователь останавливает интерфейс до тех пор, пока сериализация не будет завершена.
Вот мои шаги:
Общее
Метод запроса с использованием библиотеки ktor:
class NetworkProvider {
private val client = HttpClient()
suspend fun request(urlString: String): String {
return client.request<String>(urlString)
}
}
Метод запроса с сериализацией JSON:
suspend fun request(): CustomObject {
val json = networkProvider.request("API endpoint")
val object = Json.nonstrict.parse(CustomObject().serializer(), json)
return object
}
Выполнение запроса:
class Downloader {
var listener: DownloadListener? = null
fun download() {
CustomCoroutineScope().launch {
val object = request()
listener?.onCompleted(object)
}
}
}
Область действия диспетчера и сопрограммы:
class UIDispatcher : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatch_get_main_queue()) {
block.run()
}
}
}
internal class CustomCoroutineScope : CoroutineScope {
private val dispatcher = UIDispatcher()
private val job = Job()
override val coroutineContext: CoroutineContext
get() = dispatcher + job
}
IOS
Реализация DownloadListener
метод:
func onCompleted(object: CustomObject) {
// Update the UI
}
и позвоните по запросу
downloader.download()
Я предположил, что это должно выполняться асинхронно в основном потоке без блокировки пользовательского интерфейса.
Что я делаю не так? Я пытался использовать withContext
при вызове сопрограммы, но это не помогло.
Есть ли способ выполнения сложных задач в общем модуле без блокировки пользовательского интерфейса на конкретной платформе?