5#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h"
7#import "flutter/fml/logging.h"
8#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h"
9#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"
12#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate_internal.h"
35 [_lifeCycleDelegate release];
36 [_rootFlutterViewControllerGetter release];
41- (
BOOL)application:(UIApplication*)application
42 willFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
43 return [_lifeCycleDelegate application:application willFinishLaunchingWithOptions:launchOptions];
46- (
BOOL)application:(UIApplication*)application
47 didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
48 return [_lifeCycleDelegate application:application didFinishLaunchingWithOptions:launchOptions];
54 if (_rootFlutterViewControllerGetter != nil) {
55 return _rootFlutterViewControllerGetter();
57 UIViewController* rootViewController = _window.rootViewController;
65- (void)applicationDidEnterBackground:(UIApplication*)application {
69- (void)applicationWillEnterForeground:(UIApplication*)application {
73- (void)applicationWillResignActive:(UIApplication*)application {
77- (void)applicationDidBecomeActive:(UIApplication*)application {
81- (void)applicationWillTerminate:(UIApplication*)application {
84#pragma GCC diagnostic push
85#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
86- (void)application:(UIApplication*)application
87 didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
88 [_lifeCycleDelegate application:application
89 didRegisterUserNotificationSettings:notificationSettings];
91#pragma GCC diagnostic pop
93- (void)application:(UIApplication*)application
94 didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
95 [_lifeCycleDelegate application:application
96 didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
99- (void)application:(UIApplication*)application
100 didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
101 [_lifeCycleDelegate application:application
102 didFailToRegisterForRemoteNotificationsWithError:error];
105#pragma GCC diagnostic push
106#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
107- (void)application:(UIApplication*)application
108 didReceiveLocalNotification:(UILocalNotification*)notification {
109 [_lifeCycleDelegate application:application didReceiveLocalNotification:notification];
111#pragma GCC diagnostic pop
113- (void)userNotificationCenter:(UNUserNotificationCenter*)center
114 willPresentNotification:(UNNotification*)notification
115 withCompletionHandler:
116 (
void (^)(UNNotificationPresentationOptions
options))completionHandler {
117 if ([_lifeCycleDelegate respondsToSelector:_cmd]) {
118 [_lifeCycleDelegate userNotificationCenter:center
119 willPresentNotification:notification
120 withCompletionHandler:completionHandler];
127- (void)userNotificationCenter:(UNUserNotificationCenter*)center
128 didReceiveNotificationResponse:(UNNotificationResponse*)response
129 withCompletionHandler:(
void (^)(
void))completionHandler {
130 if ([_lifeCycleDelegate respondsToSelector:_cmd]) {
131 [_lifeCycleDelegate userNotificationCenter:center
132 didReceiveNotificationResponse:response
133 withCompletionHandler:completionHandler];
137- (
BOOL)openURL:(NSURL*)url {
138 NSNumber* isDeepLinkingEnabled =
139 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FlutterDeepLinkingEnabled"];
140 if (!isDeepLinkingEnabled.boolValue) {
145 if (flutterViewController) {
146 [flutterViewController.engine
147 waitForFirstFrame:3.0
148 callback:^(BOOL didTimeout) {
151 << "Timeout waiting for the first frame when launching an URL.";
153 [flutterViewController.engine.navigationChannel
154 invokeMethod:@"pushRouteInformation"
156 @"location" : url.absoluteString ?: [NSNull null],
162 FML_LOG(
ERROR) <<
"Attempting to open an URL without a Flutter RootViewController.";
168- (
BOOL)application:(UIApplication*)application
170 options:(NSDictionary<UIApplicationOpenURLOptionsKey,
id>*)options {
171 if ([_lifeCycleDelegate application:application openURL:url
options:
options]) {
174 return [
self openURL:url];
177- (
BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
178 return [_lifeCycleDelegate application:application handleOpenURL:url];
181- (
BOOL)application:(UIApplication*)application
183 sourceApplication:(NSString*)sourceApplication
184 annotation:(
id)annotation {
185 return [_lifeCycleDelegate application:application
187 sourceApplication:sourceApplication
188 annotation:annotation];
191- (void)application:(UIApplication*)application
192 performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
193 completionHandler:(
void (^)(
BOOL succeeded))completionHandler {
194 [_lifeCycleDelegate application:application
195 performActionForShortcutItem:shortcutItem
196 completionHandler:completionHandler];
199- (void)application:(UIApplication*)application
200 handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
201 completionHandler:(nonnull
void (^)())completionHandler {
202 [_lifeCycleDelegate application:application
203 handleEventsForBackgroundURLSession:identifier
204 completionHandler:completionHandler];
207- (
BOOL)application:(UIApplication*)application
208 continueUserActivity:(NSUserActivity*)userActivity
210 (
void (^)(NSArray<
id<UIUserActivityRestoring>>* __nullable restorableObjects))
212 if ([_lifeCycleDelegate application:application
213 continueUserActivity:userActivity
214 restorationHandler:restorationHandler]) {
217 return [
self openURL:userActivity.webpageURL];
220#pragma mark - FlutterPluginRegistry methods. All delegating to the rootViewController
224 if (flutterRootViewController) {
225 return [[flutterRootViewController
pluginRegistry] registrarForPlugin:pluginKey];
230- (
BOOL)hasPlugin:(NSString*)pluginKey {
232 if (flutterRootViewController) {
233 return [[flutterRootViewController
pluginRegistry] hasPlugin:pluginKey];
238- (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey {
240 if (flutterRootViewController) {
241 return [[flutterRootViewController
pluginRegistry] valuePublishedByPlugin:pluginKey];
246#pragma mark - Selectors handling
249 [_lifeCycleDelegate addDelegate:delegate];
252#pragma mark - UIApplicationDelegate method dynamic implementation
254- (
BOOL)respondsToSelector:(
SEL)selector {
255 if ([_lifeCycleDelegate isSelectorAddedDynamically:selector]) {
256 return [
self delegateRespondsSelectorToPlugins:selector];
258 return [
super respondsToSelector:selector];
261- (
BOOL)delegateRespondsSelectorToPlugins:(
SEL)selector {
262 if ([_lifeCycleDelegate hasPluginThatRespondsToSelector:selector]) {
263 return [_lifeCycleDelegate respondsToSelector:selector];
269- (
id)forwardingTargetForSelector:(
SEL)aSelector {
270 if ([_lifeCycleDelegate isSelectorAddedDynamically:aSelector]) {
271 [
self logCapabilityConfigurationWarningIfNeeded:aSelector];
272 return _lifeCycleDelegate;
274 return [
super forwardingTargetForSelector:aSelector];
281- (void)logCapabilityConfigurationWarningIfNeeded:(
SEL)selector {
282 NSArray* backgroundModesArray =
283 [[NSBundle mainBundle] objectForInfoDictionaryKey:kUIBackgroundMode];
284 NSSet* backgroundModesSet = [[[NSSet alloc] initWithArray:backgroundModesArray] autorelease];
285 if (selector ==
@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)) {
288 @"You've implemented -[<UIApplicationDelegate> "
289 @"application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need "
290 @"to add \"remote-notification\
" to the list of your supported UIBackgroundModes in your "
293 }
else if (selector ==
@selector(application:performFetchWithCompletionHandler:)) {
295 NSLog(
@"You've implemented -[<UIApplicationDelegate> "
296 @"application:performFetchWithCompletionHandler:], but you still need to add \"fetch\
" "
297 @"to the list of your supported UIBackgroundModes in your Info.plist.");
302#pragma mark - State Restoration
304- (
BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder {
305 [coder encodeInt64:self.lastAppModificationTime forKey:kRestorationStateAppModificationKey];
309- (
BOOL)application:(UIApplication*)application shouldRestoreApplicationState:(NSCoder*)coder {
310 int64_t stateDate = [coder decodeInt64ForKey:kRestorationStateAppModificationKey];
311 return self.lastAppModificationTime == stateDate;
314- (
BOOL)application:(UIApplication*)application shouldSaveSecureApplicationState:(NSCoder*)coder {
315 [coder encodeInt64:self.lastAppModificationTime forKey:kRestorationStateAppModificationKey];
319- (
BOOL)application:(UIApplication*)application
320 shouldRestoreSecureApplicationState:(NSCoder*)coder {
321 int64_t stateDate = [coder decodeInt64ForKey:kRestorationStateAppModificationKey];
322 return self.lastAppModificationTime == stateDate;
325- (int64_t)lastAppModificationTime {
327 NSError*
error = nil;
328 [[[NSBundle mainBundle] executableURL] getResourceValue:&fileDate
329 forKey:NSURLContentModificationDateKey
331 NSAssert(
error == nil,
@"Cannot obtain modification date of main bundle: %@",
error);
332 return [fileDate timeIntervalSince1970];
static void copy(void *dst, const uint8_t *src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[])
FlutterViewController *(^ rootFlutterViewControllerGetter)(void)
const uint8_t uint32_t uint32_t GError ** error
#define FML_LOG(severity)
id< FlutterPluginRegistry > pluginRegistry()
static NSString *const kRemoteNotificationCapabitiliy
static NSString *const kUIBackgroundMode
static NSString *const kBackgroundFetchCapatibility
static NSString *const kRestorationStateAppModificationKey