Вопрос или проблема
Я сталкиваюсь с неожиданным поведением при работе с глубокими ссылками, используя глубокие ссылки навигации Jetpack.
URL-адреса, которые я хочу открыть в приложении, следующие:
- “https://(…)организация/3679-tанцевальная-компания-058/product/132”
- “https://(…)организация/3679-tанцевальная-компания-058”
Когда я пробую первую ссылку, она работает как ожидалось (открывает экран организации в приложении). Однако, когда открываю вторую ссылку, она все равно открывает экран организации, а не экран продукта.
У меня есть 2 глубокие ссылки:
<deepLink
android:id="@+id/productSeoDeeplink"
app:uri=".*/product/{productId}-.*" />
<deepLink
android:id="@+id/organisationSeoDeeplink"
app:uri=".*/организация/{organisationId}-.*" />
Я ожидал, что будет использована более специфичная глубокая ссылка (/products) вместо самой общей.
Я знаю, что происходит так, что первая глубокая ссылка также совпадает со второй глубокой ссылкой, поэтому открывается первый экран. Но разве не должна использоваться более специфичная глубокая ссылка?
Если я изменю вторую глубокую ссылку на
<deepLink
android:id="@+id/organisationSeoDeeplink"
app:uri=".*/организация/{organisationId}/product/{productId}-.*" />
Это работает как ожидалось. Не хватает ли чего-то?
Ответ или решение
Судя по вашему описанию, вы столкнулись с проблемой с приоритетом deep link-ов в Android Jetpack Navigation. Давайте разберем это более подробно.
Проблема, с которой вы столкнулись, заключается в том, что два вашего deeplink-ресурса пересекаются по условиям. Когда вы используете URL, который подходит под оба условия, Jetpack Navigation будет использовать правило, которое первично и совпадает с его шаблоном.
Объяснение
- Маскировка шаблонов:
productSeoDeeplink
: этот шаблон использует выражение.*/product/{productId}-.*
, что подразумевает, что он будет захватывать любые URL, которые содержат/product/
и следуют за этим идентификатором продукта.organisationSeoDeeplink
: ваш шаблон.*/organisation/{organisationId}-.*
захватывает URL, которые содержат/organisation/
и следуют за этим идентификатором.
Когда вы открываете URL без идентификатора продукта (т.е. второй пример), система продолжает обрабатывать это как совпадение с productSeoDeeplink
из-за общего .*/
в шаблонах, что приводит к неожиданному результату.
Решение
Вы правильно идентифицировали, что лучший способ решить эту проблему — сделать шаблон для вашего organisationSeoDeeplink
более специфичным, чтобы он не конфликтовал с productSeoDeeplink
. Ваш исправленный шаблон выглядит следующим образом:
<deepLink
android:id="@+id/organisationSeoDeeplink"
app:uri=".*/organisation/{organisationId}/product/{productId}-.*" />
При этом изменении, ваш deeplink для организации будет узкоспециализированным и будет принимать только URL, которые действительно содержат как organisationId
, так и productId
. Это поможет избежать нежелательного поведения и исключит возможность совпадения.
Рекомендации
-
Тестируйте шаблоны: Всегда проверяйте, как ваши шаблоны совпадают с различными URL. Составьте список URL, которые вы хотите поддерживать, и проверьте их на соответствие каждому шаблону.
-
Используйте более точные паттерны: Важно проектировать deeplink-ы с учетом наиболее специфичных требований, чтобы избежать конфликтов.
-
Документация: Ознакомьтесь с официальной документацией Jetpack Navigation на предмет использования deeplink-ов, чтобы понять, как можно избежать подобных проблем в будущем.
Следуя вышеизложенным рекомендациям и изменениям, вы сможете обеспечить корректное поведение вашего приложения при использовании deeplink-ов. Это поможет улучшить пользовательский опыт при взаимодействии с вашим приложением.