Глубокая ссылка Flutter как для iOS, так и для веба

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

Я использую 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, что не совпадает с ожидаемыми маршрутами вашего приложения.

Решение

  1. Настройка маршрутов:
    Ваша конфигурация маршрутов должна учитывать, что 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);
             },
           ),
         ],
       ),
     ],
    );
  2. Настройка файла AASA:
    Убедитесь, что файл AASA правильно настроен. У вас уже прописан путь к подкаталогу, но вам тоже нужно удостовериться, что прописанный идентификатор приложения (appID) соответствует действительности. Проверьте, корректно ли указаны teamID и appID. Обновлённый файл должен выглядеть следующим образом:

    {
     "applinks": {
       "apps": [],
       "details": [
         {
           "appIDs": [
             "YOUR_TEAMID.YOUR_APPID" // Убедитесь, что здесь указаны правильные значения
           ],
           "paths": [
             "/subPath1/subPath2/myApp/*"
           ]
         }
       ]
     }
    }
  3. Обработка полнофункциональных 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-адреса, получаемые вашим приложением, и извлекаете из них необходимые компоненты для навигации. Это поможет устранить ошибки и обеспечит качественное взаимодействие пользователей с вашим приложением, независимо от платформы.

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

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