iOS端未启动App时,Go Router实现Deep Link无法跳转至正确页面
iOS端GoRouter深度链接冷启动异常问题
我使用GoRouter实现深度链接功能,Android端完全正常,但iOS端存在异常:当App处于后台运行状态时,打开深度链接URL能正常跳转到对应页面;但App完全关闭时,打开链接只会进入默认的登录页面(首页)。
配置信息
Info.plist
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <string>appscheme</string> <string>${GOOGLE_REVERSED_CLIENT_ID}</string> </array> </dict> </array>
app.dart
MaterialApp.router( debugShowCheckedModeBanner: false, routerConfig: GoRouter( routes: [ GoRoute( path: '/', builder: (context, state) => const LoginPage( key: Key('loginPage',),), ), GoRoute( path: '/sign-up', builder: (context, state) => const SignUpPage( key: Key('signUpPage'), ), ), ], ), );
测试命令
xcrun simctl openurl booted "appscheme:/sign-up"
问题原因与解决办法
iOS App冷启动时,深度链接的初始URL不会自动被GoRouter识别处理,需要手动捕获URL并传递给Flutter侧的路由配置。
步骤1:iOS端捕获启动URL
修改iOS项目的AppDelegate.swift,添加代码捕获冷启动及后续的深度链接URL:
import UIKit import Flutter @UIApplicationMain class AppDelegate: FlutterAppDelegate { var initialUrl: URL? override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 捕获冷启动时的深度链接URL if let url = launchOptions?[.url] as? URL { initialUrl = url } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { // 将URL传递给Flutter侧 let channel = FlutterMethodChannel(name: "app/deep_link", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger) channel.invokeMethod("handleDeepLink", arguments: url.absoluteString) return true } override func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if let url = userActivity.webpageURL { let channel = FlutterMethodChannel(name: "app/deep_link", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger) channel.invokeMethod("handleDeepLink", arguments: url.absoluteString) } return true } }
步骤2:Flutter侧接收并处理URL
在app.dart中通过MethodChannel接收URL,让GoRouter完成跳转:
import 'package:flutter/services.dart'; import 'package:go_router/go_router.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { final _deepLinkChannel = const MethodChannel('app/deep_link'); late final GoRouter _router; @override void initState() { super.initState(); _initRouter(); _setupDeepLinkListener(); } void _initRouter() { _router = GoRouter( routes: [ GoRoute( path: '/', builder: (context, state) => const LoginPage(key: Key('loginPage')), ), GoRoute( path: '/sign-up', builder: (context, state) => const SignUpPage(key: Key('signUpPage')), ), ], ); } void _setupDeepLinkListener() { // 监听iOS传递的深度链接 _deepLinkChannel.setMethodCallHandler((call) async { if (call.method == 'handleDeepLink') { final url = call.arguments as String; // 让GoRouter处理跳转 _router.push(url); } }); } @override Widget build(BuildContext context) { return MaterialApp.router( debugShowCheckedModeBanner: false, routerConfig: _router, ); } }
补充说明
- 你现有
Info.plist的URL Scheme配置是正确的,无需修改。 - 如果使用Universal Links,还需额外配置
apple-app-site-association文件,但当前自定义Scheme场景下,上述代码已覆盖冷启动和后台唤醒的深度链接处理。
内容的提问来源于stack exchange,提问作者Sudeep Bashistha
相关产品推荐
相关产品推荐

