7 #import "flutter/shell/platform/darwin/common/InternalFlutterSwiftCommon/InternalFlutterSwiftCommon.h"
35 - (instancetype)init {
36 if (
self = [super init]) {
44 return [
self.launchEngine takeEngine];
47 - (BOOL)application:(UIApplication*)application
48 willFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
49 return [
self.lifeCycleDelegate application:application
50 willFinishLaunchingWithOptions:launchOptions];
53 - (BOOL)application:(UIApplication*)application
54 didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
55 return [
self.lifeCycleDelegate application:application
56 didFinishLaunchingWithOptions:launchOptions];
62 if (_rootFlutterViewControllerGetter != nil) {
63 return _rootFlutterViewControllerGetter();
65 UIViewController* rootViewController = _window.rootViewController;
73 - (void)applicationDidEnterBackground:(UIApplication*)application {
77 - (void)applicationWillEnterForeground:(UIApplication*)application {
81 - (void)applicationWillResignActive:(UIApplication*)application {
85 - (void)applicationDidBecomeActive:(UIApplication*)application {
89 - (void)applicationWillTerminate:(UIApplication*)application {
92 #pragma GCC diagnostic push
93 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
94 - (void)application:(UIApplication*)application
95 didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
96 [
self.lifeCycleDelegate application:application
97 didRegisterUserNotificationSettings:notificationSettings];
99 #pragma GCC diagnostic pop
101 - (void)application:(UIApplication*)application
102 didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
103 [
self.lifeCycleDelegate application:application
104 didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
107 - (void)application:(UIApplication*)application
108 didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
109 [
self.lifeCycleDelegate application:application
110 didFailToRegisterForRemoteNotificationsWithError:error];
113 #pragma GCC diagnostic push
114 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
115 - (void)application:(UIApplication*)application
116 didReceiveLocalNotification:(UILocalNotification*)notification {
117 [
self.lifeCycleDelegate application:application didReceiveLocalNotification:notification];
119 #pragma GCC diagnostic pop
121 - (void)userNotificationCenter:(UNUserNotificationCenter*)center
122 willPresentNotification:(UNNotification*)notification
123 withCompletionHandler:
124 (
void (^)(UNNotificationPresentationOptions options))completionHandler {
125 if ([
self.lifeCycleDelegate respondsToSelector:_cmd]) {
126 [
self.lifeCycleDelegate userNotificationCenter:center
127 willPresentNotification:notification
128 withCompletionHandler:completionHandler];
135 - (void)userNotificationCenter:(UNUserNotificationCenter*)center
136 didReceiveNotificationResponse:(UNNotificationResponse*)response
137 withCompletionHandler:(
void (^)(
void))completionHandler {
138 if ([
self.lifeCycleDelegate respondsToSelector:_cmd]) {
139 [
self.lifeCycleDelegate userNotificationCenter:center
140 didReceiveNotificationResponse:response
141 withCompletionHandler:completionHandler];
145 - (BOOL)isFlutterDeepLinkingEnabled {
146 NSNumber* isDeepLinkingEnabled =
147 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FlutterDeepLinkingEnabled"];
149 return isDeepLinkingEnabled ? [isDeepLinkingEnabled boolValue] : YES;
153 - (BOOL)application:(UIApplication*)application
155 options:(NSDictionary<UIApplicationOpenURLOptionsKey,
id>*)options {
156 if ([
self.lifeCycleDelegate application:application openURL:url options:options]) {
161 return [
self handleOpenURL:url options:options relayToSystemIfUnhandled:NO];
165 - (BOOL)handleOpenURL:(NSURL*)url
166 options:(NSDictionary<UIApplicationOpenURLOptionsKey,
id>*)options
167 relayToSystemIfUnhandled:(BOOL)throwBack {
169 if (flutterApplication == nil) {
172 if (![
self isFlutterDeepLinkingEnabled]) {
177 if (flutterViewController) {
178 [flutterViewController sendDeepLinkToFramework:url
179 completionHandler:^(BOOL success) {
180 if (!success && throwBack) {
182 [flutterApplication openURL:url
184 completionHandler:nil];
188 [FlutterLogger logError:@"Attempting to open an URL without a Flutter RootViewController."];
194 - (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
195 return [
self.lifeCycleDelegate application:application handleOpenURL:url];
198 - (BOOL)application:(UIApplication*)application
200 sourceApplication:(NSString*)sourceApplication
201 annotation:(
id)annotation {
202 return [
self.lifeCycleDelegate application:application
204 sourceApplication:sourceApplication
205 annotation:annotation];
208 - (void)application:(UIApplication*)application
209 performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
210 completionHandler:(
void (^)(BOOL succeeded))completionHandler {
211 [
self.lifeCycleDelegate application:application
212 performActionForShortcutItem:shortcutItem
213 completionHandler:completionHandler];
216 - (void)application:(UIApplication*)application
217 handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
218 completionHandler:(nonnull
void (^)())completionHandler {
219 [
self.lifeCycleDelegate application:application
220 handleEventsForBackgroundURLSession:identifier
221 completionHandler:completionHandler];
225 - (BOOL)application:(UIApplication*)application
226 continueUserActivity:(NSUserActivity*)userActivity
228 (
void (^)(NSArray<
id<UIUserActivityRestoring>>* __nullable restorableObjects))
230 if ([
self.lifeCycleDelegate application:application
231 continueUserActivity:userActivity
232 restorationHandler:restorationHandler]) {
236 return [
self handleOpenURL:userActivity.webpageURL options:@{} relayToSystemIfUnhandled:YES];
239 #pragma mark - FlutterPluginRegistry methods. All delegating to the rootViewController
242 if (_weakRegistrant) {
243 return _weakRegistrant;
245 if (_strongRegistrant) {
246 return _strongRegistrant;
254 _strongRegistrant = nil;
256 _weakRegistrant = nil;
263 if (flutterRootViewController) {
264 return [[flutterRootViewController
pluginRegistry] registrarForPlugin:pluginKey];
266 return [
self.launchEngine.engine registrarForPlugin:pluginKey];
269 - (BOOL)hasPlugin:(NSString*)pluginKey {
271 if (flutterRootViewController) {
272 return [[flutterRootViewController
pluginRegistry] hasPlugin:pluginKey];
274 return [
self.launchEngine.engine hasPlugin:pluginKey];
277 - (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey {
279 if (flutterRootViewController) {
280 return [[flutterRootViewController
pluginRegistry] valuePublishedByPlugin:pluginKey];
282 return [
self.launchEngine.engine valuePublishedByPlugin:pluginKey];
285 #pragma mark - Selectors handling
288 [
self.lifeCycleDelegate addDelegate:delegate];
291 #pragma mark - UIApplicationDelegate method dynamic implementation
293 - (BOOL)respondsToSelector:(
SEL)selector {
294 if ([
self.lifeCycleDelegate isSelectorAddedDynamically:selector]) {
295 return [
self delegateRespondsSelectorToPlugins:selector];
297 return [
super respondsToSelector:selector];
300 - (BOOL)delegateRespondsSelectorToPlugins:(
SEL)selector {
301 if ([
self.lifeCycleDelegate hasPluginThatRespondsToSelector:selector]) {
302 return [
self.lifeCycleDelegate respondsToSelector:selector];
308 - (id)forwardingTargetForSelector:(
SEL)aSelector {
309 if ([
self.lifeCycleDelegate isSelectorAddedDynamically:aSelector]) {
310 [
self logCapabilityConfigurationWarningIfNeeded:aSelector];
311 return self.lifeCycleDelegate;
313 return [
super forwardingTargetForSelector:aSelector];
320 - (void)logCapabilityConfigurationWarningIfNeeded:(
SEL)selector {
321 NSArray* backgroundModesArray =
322 [[NSBundle mainBundle] objectForInfoDictionaryKey:kUIBackgroundMode];
323 NSSet* backgroundModesSet = [[NSSet alloc] initWithArray:backgroundModesArray];
324 if (selector ==
@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)) {
327 @"You've implemented -[<UIApplicationDelegate> "
328 @"application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need "
329 @"to add \"remote-notification\
" to the list of your supported UIBackgroundModes in your "
332 }
else if (selector ==
@selector(application:performFetchWithCompletionHandler:)) {
334 NSLog(
@"You've implemented -[<UIApplicationDelegate> "
335 @"application:performFetchWithCompletionHandler:], but you still need to add \"fetch\
" "
336 @"to the list of your supported UIBackgroundModes in your Info.plist.");
341 #pragma mark - State Restoration
343 - (BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder {
344 [coder encodeInt64:self.lastAppModificationTime forKey:kRestorationStateAppModificationKey];
348 - (BOOL)application:(UIApplication*)application shouldRestoreApplicationState:(NSCoder*)coder {
349 int64_t stateDate = [coder decodeInt64ForKey:kRestorationStateAppModificationKey];
350 return self.lastAppModificationTime == stateDate;
353 - (BOOL)application:(UIApplication*)application shouldSaveSecureApplicationState:(NSCoder*)coder {
354 [coder encodeInt64:self.lastAppModificationTime forKey:kRestorationStateAppModificationKey];
358 - (BOOL)application:(UIApplication*)application
359 shouldRestoreSecureApplicationState:(NSCoder*)coder {
360 int64_t stateDate = [coder decodeInt64ForKey:kRestorationStateAppModificationKey];
361 return self.lastAppModificationTime == stateDate;
364 - (int64_t)lastAppModificationTime {
366 NSError* error = nil;
367 [[[NSBundle mainBundle] executableURL] getResourceValue:&fileDate
368 forKey:NSURLContentModificationDateKey
370 NSAssert(error == nil,
@"Cannot obtain modification date of main bundle: %@", error);
371 return [fileDate timeIntervalSince1970];
static NSString *const kRemoteNotificationCapabitiliy
static FLUTTER_ASSERT_ARC NSString *const kUIBackgroundMode
static NSString *const kBackgroundFetchCapatibility
static NSString *const kRestorationStateAppModificationKey
__weak NSObject< FlutterPluginRegistrant > * _weakRegistrant
NSObject< FlutterPluginRegistrant > * _strongRegistrant
NSObject< FlutterPluginRegistrant > * pluginRegistrant
UIApplication * application
id< FlutterPluginRegistry > pluginRegistry()