Вопрос или проблема
Я использую go_router (GoRouter) с Flutter и пытаюсь сделать так, чтобы как маршруты веба, так и маршруты глубоких ссылок на iOS работали, одновременно размещая свое веб-приложение по пользовательскому base-href. Походу маршрутизация работает нормально, когда я размещаю на своем веб-сервере и получаю доступ к ссылкам по моему пользовательскому base-href с добавленным маршрутом.
Мои маршруты настроены следующим образом:
/// Конфигурация маршрутов.
final GoRouter _router = GoRouter(
routes: <RouteBase>[
GoRoute(
path: "https://stackoverflow.com/",
builder: (BuildContext context, GoRouterState state) {
return const AuthPage();
},
routes: <RouteBase>[
GoRoute(
path: '/AuthPage',
builder: (BuildContext context, GoRouterState state) {
return const AuthPage();
},
),
GoRoute(
path: '/AuthPage/:uuid',
builder: (BuildContext context, GoRouterState state) {
String? uuid = state.pathParameters['uuid'];
return AuthPage(uuid: uuid);
},
),
GoRoute(
path: '/ReportOffEntryPage/:uuid',
builder: (BuildContext context, GoRouterState state) {
String? uuid = state.pathParameters['uuid'];
return ReportOffEntryPage(uuid: uuid);
},
),
),
],
);
Если, например, мой веб-сервер находится по адресу https://myserver, и мой base-href установлен на /subPath1/subPath2/myApp/, я могу открыть свое приложение в браузере по адресу https://myServer/subPath1/subPath2/myApp/ReportOffEntryPage, или https://myServer/subPath1/subPath2/myApp/AuthPage, или https://myServer/subPath1/subPath2/myApp/ и маршрут обрабатывается правильно.
Однако, когда приложение развернуто на iOS и я нажимаю на ссылку в электронной почте на https://myServer/subPath1/subPath2/myApp/ReportOffEntryPage, оно открывает мое приложение, но GoRouter показывает ошибку “GoException: no routes for location: https://myServer/subPath1/subPath2/myApp/ReportOffEntryPage/” (весь URL из электронной почты). Я ожидал, что он просто использует маршрут /ReportOffEntryPage.
Мой файл AASA определен как
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": [
"teamID.appID"
],
"paths": [
"/subPath1/subPath2/myApp/*"
]
}
]
}
}
Не хватает ли мне чего-то, что позволит одновременно работать и глубоким ссылкам iOS, и веб-ссылкам с пользовательским base-href?
Ответ или решение
Глубокая интеграция ссылок в Flutter на iOS и Web с использованием go_router
Введение
Глубокая интеграция ссылок (deep linking) — это мощная функция, позволяющая улучшить пользовательский опыт, направляя пользователей непосредственно к определённым разделам вашего приложения. Использование этой функции в приложениях Flutter, которые одновременно работаю на iOS и Web, требует внимательного подхода к конфигурации. От правильной настройки маршрутов в go_router до корректного использования файла AASA для deep linking на iOS — на все эти аспекты нужно обратить особое внимание.
Проблема
У вас уже настроены маршруты для веб-приложения, и оно функционирует корректно при доступе по собственному пути /subPath1/subPath2/myApp/
. Однако, когда вы обращаетесь к вашему приложению на iOS через deep link, GoRouter выдает ошибку: GoException: no routes for location
. Это происходит из-за того, что iOS передает полный URL, включая https://myServer
, что не совпадает с ожидаемыми маршрутами вашего приложения.
Решение
-
Настройка маршрутов:
Ваша конфигурация маршрутов должна учитывать, чтоGoRouter
принимает только относительные пути. Поэтому вам стоит изменить их так, чтобы использовать относительные адреса. Пример настройки может выглядеть так:final GoRouter _router = GoRouter( routes: <RouteBase>[ GoRoute( path: '/', // Настройте путь как корневой builder: (BuildContext context, GoRouterState state) { return const AuthPage(); }, routes: <RouteBase>[ GoRoute( path: 'AuthPage', builder: (BuildContext context, GoRouterState state) { return const AuthPage(); }, ), GoRoute( path: 'AuthPage/:uuid', builder: (BuildContext context, GoRouterState state) { String? uuid = state.pathParameters['uuid']; return AuthPage(uuid: uuid); }, ), GoRoute( path: 'ReportOffEntryPage/:uuid', builder: (BuildContext context, GoRouterState state) { String? uuid = state.pathParameters['uuid']; return ReportOffEntryPage(uuid: uuid); }, ), ], ), ], );
-
Настройка файла AASA:
Убедитесь, что файл AASA правильно настроен. У вас уже прописан путь к подкаталогу, но вам тоже нужно удостовериться, что прописанный идентификатор приложения (appID
) соответствует действительности. Проверьте, корректно ли указаныteamID
иappID
. Обновлённый файл должен выглядеть следующим образом:{ "applinks": { "apps": [], "details": [ { "appIDs": [ "YOUR_TEAMID.YOUR_APPID" // Убедитесь, что здесь указаны правильные значения ], "paths": [ "/subPath1/subPath2/myApp/*" ] } ] } }
-
Обработка полнофункциональных URL:
Для корректной работы с deep links, обрабатывающими полный URL, необходимо извлекать нужную часть URL в самом приложении. Вы можете это делать, используя методonGenerateRoute
или аналогичные обработчики:void _handleDeepLink(String? url) { if (url != null) { // Удаляем часть, которая не нужна final uri = Uri.parse(url); final path = uri.path; // Используйте GoRouter для навигации _router.go(path); // Пройдите по пути } }
Заключение
С учётом вышеизложенного, важно помнить, что ключ к успешной интеграции глубоких ссылок на iOS и в веб-приложении заключается в правильно настроенных маршрутах и корректно указанном файле AASA. Убедитесь, что вы обрабатываете все URL-адреса, получаемые вашим приложением, и извлекаете из них необходимые компоненты для навигации. Это поможет устранить ошибки и обеспечит качественное взаимодействие пользователей с вашим приложением, независимо от платформы.