44
55#import " flutter/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h"
66
7- #include " flutter/fml/logging.h"
7+ #import " flutter/fml/logging.h"
88#import " flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h"
99#import " flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
10+ #import " flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate_Test.h"
11+ #import " flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h"
1012#import " flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate_internal.h"
1113
1214static NSString * kUIBackgroundMode = @" UIBackgroundModes" ;
1315static NSString * kRemoteNotificationCapabitiliy = @" remote-notification" ;
1416static NSString * kBackgroundFetchCapatibility = @" fetch" ;
1517
18+ @interface FlutterAppDelegate ()
19+ @property (nonatomic , copy ) FlutterViewController* (^rootFlutterViewControllerGetter)(void );
20+ @end
21+
1622@implementation FlutterAppDelegate {
1723 FlutterPluginAppLifeCycleDelegate* _lifeCycleDelegate;
1824}
@@ -26,6 +32,7 @@ - (instancetype)init {
2632
2733- (void )dealloc {
2834 [_lifeCycleDelegate release ];
35+ [_rootFlutterViewControllerGetter release ];
2936 [super dealloc ];
3037}
3138
@@ -41,10 +48,13 @@ - (BOOL)application:(UIApplication*)application
4148
4249// Returns the key window's rootViewController, if it's a FlutterViewController.
4350// Otherwise, returns nil.
44- + (FlutterViewController*)rootFlutterViewController {
45- UIViewController* viewController = [UIApplication sharedApplication ].keyWindow .rootViewController ;
46- if ([viewController isKindOfClass: [FlutterViewController class ]]) {
47- return (FlutterViewController*)viewController;
51+ - (FlutterViewController*)rootFlutterViewController {
52+ if (_rootFlutterViewControllerGetter != nil ) {
53+ return _rootFlutterViewControllerGetter ();
54+ }
55+ UIViewController* rootViewController = _window.rootViewController ;
56+ if ([rootViewController isKindOfClass: [FlutterViewController class ]]) {
57+ return (FlutterViewController*)rootViewController;
4858 }
4959 return nil ;
5060}
@@ -124,7 +134,28 @@ - (void)userNotificationCenter:(UNUserNotificationCenter*)center
124134- (BOOL )application : (UIApplication*)application
125135 openURL : (NSURL *)url
126136 options : (NSDictionary <UIApplicationOpenURLOptionsKey, id>*)options {
127- return [_lifeCycleDelegate application: application openURL: url options: options];
137+ if ([_lifeCycleDelegate application: application openURL: url options: options]) {
138+ return YES ;
139+ } else {
140+ FlutterViewController* flutterViewController = [self rootFlutterViewController ];
141+ if (flutterViewController) {
142+ [flutterViewController.engine
143+ waitForFirstFrame: 3.0
144+ callback: ^(BOOL didTimeout) {
145+ if (didTimeout) {
146+ FML_LOG (ERROR)
147+ << " Timeout waiting for the first frame when launching an URL." ;
148+ } else {
149+ [flutterViewController.engine.navigationChannel invokeMethod: @" pushRoute"
150+ arguments: url.path];
151+ }
152+ }];
153+ return YES ;
154+ } else {
155+ FML_LOG (ERROR) << " Attempting to open an URL without a Flutter RootViewController." ;
156+ return NO ;
157+ }
158+ }
128159}
129160
130161- (BOOL )application : (UIApplication*)application handleOpenURL : (NSURL *)url {
@@ -175,27 +206,25 @@ - (BOOL)application:(UIApplication*)application
175206#pragma mark - FlutterPluginRegistry methods. All delegating to the rootViewController
176207
177208- (NSObject <FlutterPluginRegistrar>*)registrarForPlugin:(NSString *)pluginKey {
178- UIViewController* rootViewController = _window.rootViewController ;
179- if ([rootViewController isKindOfClass: [FlutterViewController class ]]) {
180- return
181- [[(FlutterViewController*)rootViewController pluginRegistry ] registrarForPlugin: pluginKey];
209+ FlutterViewController* flutterRootViewController = [self rootFlutterViewController ];
210+ if (flutterRootViewController) {
211+ return [[flutterRootViewController pluginRegistry ] registrarForPlugin: pluginKey];
182212 }
183213 return nil ;
184214}
185215
186216- (BOOL )hasPlugin:(NSString *)pluginKey {
187- UIViewController* rootViewController = _window. rootViewController ;
188- if ([rootViewController isKindOfClass: [FlutterViewController class ]] ) {
189- return [[(FlutterViewController*)rootViewController pluginRegistry ] hasPlugin: pluginKey];
217+ FlutterViewController* flutterRootViewController = [ self rootFlutterViewController ] ;
218+ if (flutterRootViewController ) {
219+ return [[flutterRootViewController pluginRegistry ] hasPlugin: pluginKey];
190220 }
191221 return false ;
192222}
193223
194224- (NSObject *)valuePublishedByPlugin:(NSString *)pluginKey {
195- UIViewController* rootViewController = _window.rootViewController ;
196- if ([rootViewController isKindOfClass: [FlutterViewController class ]]) {
197- return [[(FlutterViewController*)rootViewController pluginRegistry ]
198- valuePublishedByPlugin: pluginKey];
225+ FlutterViewController* flutterRootViewController = [self rootFlutterViewController ];
226+ if (flutterRootViewController) {
227+ return [[flutterRootViewController pluginRegistry ] valuePublishedByPlugin: pluginKey];
199228 }
200229 return nil ;
201230}
0 commit comments