Вопрос или проблема
У меня есть многоплатформенное приложение на 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 (например, слэши) воспринимаются как разделители маршрутов, что приводит к тому, что навигационный контроллер не может найти правильный маршрут.
Решение проблемы
-
Кодирование URL: Прежде всего, когда вы передаете URL между экранами, необходимо закодировать его, чтобы избежать путаницы с символами. Это можно сделать с помощью библиотеки, позволяющей кодировать и декодировать строки URL.
-
Настройка навигации:
- Убедитесь, что вы правильно настроили навигацию между экранами. Когда вы вызываете метод
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, не стесняйтесь спрашивать!