Ответ
Deep Link — это URL, который открывает конкретный экран или контент внутри приложения. В моих Flutter-проектах это ключевая функциональность для интеграции с вебом, push-уведомлениями и кросс-платформенной навигацией.
Полная реализация с go_router (рекомендуемый подход):
// pubspec.yaml зависимости:
// go_router: ^13.0.0
// uni_links: ^0.5.1
// url_launcher: ^6.0.0
import 'package:go_router/go_router.dart';
import 'package:uni_links/uni_links.dart';
// 1. Определение маршрутов
final router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => const HomeScreen(),
),
GoRoute(
path: '/product/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return ProductScreen(productId: id);
},
),
GoRoute(
path: '/category/:name',
builder: (context, state) {
final name = state.pathParameters['name']!;
return CategoryScreen(categoryName: name);
},
),
],
errorBuilder: (context, state) => ErrorScreen(error: state.error),
);
// 2. Обработка deep links в main
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Обработка cold start (приложение закрыто)
final initialUri = await getInitialUri();
if (initialUri != null) {
handleDeepLink(initialUri);
}
// Обработка warm start (приложение открыто)
uriLinkStream.listen((Uri? uri) {
if (uri != null) handleDeepLink(uri);
});
runApp(MyApp(router: router));
}
// 3. Функция обработки ссылок
void handleDeepLink(Uri uri) {
if (uri.pathSegments.length >= 2) {
final type = uri.pathSegments[0];
final id = uri.pathSegments[1];
switch (type) {
case 'product':
router.go('/product/$id');
break;
case 'category':
router.go('/category/$id');
break;
}
}
// Обработка query параметров
final params = uri.queryParameters;
if (params.containsKey('ref')) {
analytics.trackReferral(params['ref']!);
}
}
// 4. Генерация deep links
String createProductLink(String productId) {
return 'https://myapp.com/product/$productId';
}
// 5. Открытие ссылок из приложения
void shareProduct(String productId) async {
final link = createProductLink(productId);
await launchUrl(Uri.parse(link));
}
Настройка платформ:
Android (android/app/src/main/AndroidManifest.xml):
<activity android:name=".MainActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="myapp.com"
android:pathPrefix="/product/" />
</intent-filter>
</activity>
iOS (ios/Runner/Info.plist):
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
<key>FlutterDeepLinkingEnabled</key>
<true/>
Тестирование deep links:
# Android
adb shell am start -a android.intent.action.VIEW
-d "https://myapp.com/product/123"
# iOS (симулятор)
xcrun simctl openurl booted "https://myapp.com/product/123"
# iOS (устройство)
open "myapp://product/123"
Особенности из практики:
- Universal Links (iOS) требуют серверной настройки
apple-app-site-association - App Links (Android) требуют
assetlinks.jsonна сервере - Фоновая обработка через
WidgetsBindingObserver - Аналитика — отслеживание источников переходов
- Резервный вариант — открытие в браузере с кнопкой "Открыть в приложении"
В production-приложениях всегда добавляю обработку ошибок для битых ссылок и логирование всех переходов для аналитики.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶