Как передать данные URL с одной страницы на другую в Kotlin Multiplatform?

Вопрос или проблема

У меня есть многоплатформенное приложение на Kotlin, которое вызывает API, и этот API предоставляет мне URL. Я хочу использовать этот URL для открытия WebView в приложении, но постоянно получаю эту ошибку

kotlin.IllegalArgumentException: Место назначения навигации, совпадающее с маршрутом webview/https://tw.news.yahoo.com/%E6%9A%97%E9%BB%91maga-%E9%A6%AC%E6%96%AF%E5%85%8B%E9%A6%96%E5%BA%A6%E7%82%BA%E5%B7%9D%E6%99%AE%E9%80%A0%E5%8B%A2%E5%A4%A7%E6%9C%83%E7%AB%99%E5%8F%B0-043559839.html, не может быть найдено в графе навигации ComposeNavGraph startDestination={Destination route=newsList}

Вот мой код навигации

        NavHost(navController, startDestination = "newsList") {
        composable("newsList") {
            val newsViewModel = getViewModel(Unit, viewModelFactory { NewsViewModel() })
            NewsPage(newsViewModel) { news ->
                navController.navigate("webview/${news.url.orEmpty()}")
            }
        }

        composable("webview/{url}") {
            val url = it.arguments?.getString("url") ?: ""
            
            WebView(url, navController)
        }
    }

Теперь ошибка указывает на то, что я иду по неправильному маршруту, как мне это исправить?

Итак, что я узнал, так это то, что “https://stackoverflow.com/” в моем URL вызывало эту ошибку, потому что мой NavHost рассматривал все слэши как различные маршруты, к которым ему нужно было добраться, чего я не хотел делать.

Я решил эту проблему, закодировав URL следующим образом

            composable("newsList") {
            val newsViewModel = getViewModel(Unit, viewModelFactory { NewsViewModel() })
            NewsPage(newsViewModel) { news ->
                navController.navigate("webview/${UrlEncoderUtil.encode(news.url.orEmpty())}")
            }
        }

А затем я декодировал его прямо перед передачей в WebView следующим образом

            composable("webview/{url}") {
            val url = it.arguments?.getString("url") ?: ""
            val decodedUrl = UrlEncoderUtil.decode(url)
            WebView(decodedUrl, navController)
        }

Я использовал эту зависимость для кодирования и декодирования URL

implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.4.0")

Ответ или решение

Чтобы передать данные URL с одной страницы на другую в приложении Kotlin Multi Platform, вам необходимо правильно настроить навигационный граф и использовать кодирование URL, чтобы избежать ошибок, связанных с символами в строке. В вашем случае, ошибка возникает из-за того, что специальные символы в URL (например, слэши) воспринимаются как разделители маршрутов, что приводит к тому, что навигационный контроллер не может найти правильный маршрут.

Решение проблемы

  1. Кодирование URL: Прежде всего, когда вы передаете URL между экранами, необходимо закодировать его, чтобы избежать путаницы с символами. Это можно сделать с помощью библиотеки, позволяющей кодировать и декодировать строки URL.

  2. Настройка навигации:

    • Убедитесь, что вы правильно настроили навигацию между экранами. Когда вы вызываете метод navController.navigate(), убедитесь, что вы используете закодированный URL.

Вот как это можно реализовать в вашем случае:

Кодировка URL перед навигацией

В вашем коде измените участок, где вы переходите на экран с WebView, следующим образом:

composable("newsList") {
    val newsViewModel = getViewModel(Unit, viewModelFactory { NewsViewModel() })
    NewsPage(newsViewModel) { news ->
        // Кодируем URL перед навигацией
        val encodedUrl = UrlEncoderUtil.encode(news.url.orEmpty())
        navController.navigate("webview/$encodedUrl")
    }
}

Декодирование URL перед отображением

На целевом экране с WebView вам необходимо декодировать URL перед его использованием:

composable("webview/{url}") { backStackEntry ->
    val url = backStackEntry.arguments?.getString("url") ?: ""
    // Декодируем URL
    val decodedUrl = UrlEncoderUtil.decode(url)
    WebView(decodedUrl, navController)
}

Добавление зависимости для кодирования и декодирования URL

Не забудьте добавить зависимость для библиотеки кодировки URL в ваш build.gradle файл:

implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.4.0")

Итог

С помощью этой настройки вы сможете избежать ошибок, связанных с недоступностью маршрутов из-за неправильного разбора URL. Кодирование и декодирование строк URL обеспечит корректную навигацию и откроет необходимый веб-контент в вашем приложении.

Если у вас возникнут дополнительные вопросы по настройке навигации или кодированию URL, не стесняйтесь спрашивать!

Оцените материал
Добавить комментарий

Капча загружается...