Вопрос или проблема
Я внедрил go_router для использования глубоких ссылок в своем приложении, но для некоторых путей мне нужно игнорировать глубокую ссылку и открывать их в браузере.
Например, когда пользователь нажимает на следующую URL-адрес https://example.com/login, глубокая ссылка работает отлично и открывает мое Flutter-приложение на определенной странице.
Однако, когда пользователь нажимает на https://example.com/privacy, мне нужно, чтобы эта ссылка открывалась в стандартном браузере, а не в моем приложении.
Я искал решение, но результат всегда один и тот же: ссылка всегда открывается в моем приложении.
Я пробовал использовать пакет launchUrl, но результат по-прежнему тот же:
launchUrl(Uri, mode: LaunchMode.externalApplication);
Я пытался использовать все доступные варианты LaunchMode, но ничего не работает.
Мне нужно открыть некоторые пути в браузере, а другие в моем приложении.
Пути – это некоторые примеры, мне нужно, чтобы все пути, не указанные в маршрутной карте, переходили на веб-страницу.
Ответ или решение
Чтобы реализовать логику обработки глубинной ссылки (deeplink) в вашем приложении Flutter с использованием пакета go_router
, при этом игнорируя некоторые пути и открывая их в браузере, можно воспользоваться следующим подходом.
Шаг 1: Настройка go_router
Вам нужно установить go_router для управления маршрутами в вашем приложении. Вот пример того, как можно настроить маршруты:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final GoRouter _router = GoRouter(
routes: [
GoRoute(
path: '/login',
builder: (context, state) => LoginPage(),
),
GoRoute(
path: '/home',
builder: (context, state) => HomePage(),
),
// Далее добавьте маршруты, которые вы хотите поддерживать
// Также можно обработать любые другие пути
GoRoute(
path: '/:path',
redirect: (context, state) {
// Игнорировать путь '/privacy' и редиректить его на браузер
if (state.params['path'] == 'privacy') {
_launchURL('https://example.com/privacy');
return null; // Не открывайте экран в приложении
}
return null; // Иначе используем стандартную логику маршрутизации
},
),
],
);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerDelegate: _router.routerDelegate,
routeInformationParser: _router.routeInformationParser,
);
}
void _launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url, forceSafariVC: false, forceWebView: false);
} else {
throw 'Could not launch $url';
}
}
}
// Пример страницы входа
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Login')),
body: Center(child: Text('Login Page')),
);
}
}
// Пример домашней страницы
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: Center(child: Text('Home Page')),
);
}
}
Шаг 2: Логика редиректа
В данном коде вы используете GoRoute
с параметром redirect
, чтобы обрабатывать все пути, которые не указаны в вашей конфигурации маршрутов. Если путь совпадает с /privacy
, вызовется функция _launchURL
, чтобы открыть соответствующий URL в браузере.
Шаг 3: Доработка
Если у вас есть другие пути, которые вы также хотите игнорировать и открывать в браузере, вы можете добавить дополнительные условия внутри редиректа. Например:
if (state.params['path'] == 'privacy' || state.params['path'] == 'terms') {
_launchURL('https://example.com/${state.params['path']}');
return null; // Не открывайте экран в приложении
}
Заключение
Такой подход позволит вашему приложения открывать определенные страницы, такие как "Условия использования" и "Политику конфиденциальности", в браузере, в то время как другие страницы будут открываться внутри самого приложения. Убедитесь, что для других маршрутов, которые вы хотите поддерживать, вы добавили соответствующие переходы в маршрутах GoRoute
.