7 #include "flutter/fml/logging.h"
8 #include "flutter/fml/paths.h"
9 #include "flutter/lib/ui/plugins/callback_cache.h"
18 @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:),
19 @selector(application:performFetchWithCompletionHandler:)};
22 - (void)handleDidEnterBackground:(NSNotification*)notification
23 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions");
24 - (void)handleWillEnterForeground:(NSNotification*)notification
25 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions");
26 - (void)handleWillResignActive:(NSNotification*)notification
27 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions");
28 - (void)handleDidBecomeActive:(NSNotification*)notification
29 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions");
30 - (void)handleWillTerminate:(NSNotification*)notification
31 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions");
35 UIBackgroundTaskIdentifier _debugBackgroundTask;
41 - (void)addObserverFor:(NSString*)name selector:(
SEL)selector {
42 [[NSNotificationCenter defaultCenter] addObserver:self selector:selector name:name object:nil];
45 - (instancetype)init {
46 if (
self = [super init]) {
50 [
self addObserverFor:UIApplicationDidEnterBackgroundNotification
51 selector:@selector(handleDidEnterBackground:)];
52 [
self addObserverFor:UIApplicationWillEnterForegroundNotification
53 selector:@selector(handleWillEnterForeground:)];
54 [
self addObserverFor:UIApplicationWillResignActiveNotification
55 selector:@selector(handleWillResignActive:)];
56 [
self addObserverFor:UIApplicationDidBecomeActiveNotification
57 selector:@selector(handleDidBecomeActive:)];
58 [
self addObserverFor:UIApplicationWillTerminateNotification
59 selector:@selector(handleWillTerminate:)];
61 _delegates = [NSPointerArray weakObjectsPointerArray];
62 _debugBackgroundTask = UIBackgroundTaskInvalid;
67 static BOOL IsPowerOfTwo(NSUInteger x) {
68 return x != 0 && (x & (x - 1)) == 0;
71 - (BOOL)isSelectorAddedDynamically:(
SEL)selector {
73 if (selector == aSelector) {
80 - (BOOL)hasPluginThatRespondsToSelector:(
SEL)selector {
81 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in [
_delegates allObjects]) {
85 if ([delegate respondsToSelector:selector]) {
93 [_delegates addPointer:(__bridge void*)delegate];
99 - (BOOL)application:(UIApplication*)application
100 didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
101 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in [
_delegates allObjects]) {
105 if ([delegate respondsToSelector:_cmd]) {
106 if (![delegate application:application didFinishLaunchingWithOptions:launchOptions]) {
114 - (BOOL)application:(UIApplication*)application
115 willFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
116 flutter::DartCallbackCache::LoadCacheFromDisk();
117 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in [
_delegates allObjects]) {
121 if ([delegate respondsToSelector:_cmd]) {
122 if (![delegate application:application willFinishLaunchingWithOptions:launchOptions]) {
130 - (void)handleDidEnterBackground:(NSNotification*)notification
131 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions") {
132 UIApplication* application = [UIApplication sharedApplication];
133 #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
139 _debugBackgroundTask = [application
140 beginBackgroundTaskWithName:@"Flutter debug task"
142 if (_debugBackgroundTask != UIBackgroundTaskInvalid) {
143 [application endBackgroundTask:_debugBackgroundTask];
144 _debugBackgroundTask = UIBackgroundTaskInvalid;
147 << "\nThe OS has terminated the Flutter debug connection for being "
148 "inactive in the background for too long.\n\n"
149 "There are no errors with your Flutter application.\n\n"
150 "To reconnect, launch your application again via 'flutter run'";
153 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
157 if ([delegate respondsToSelector:
@selector(applicationDidEnterBackground:)]) {
163 - (void)handleWillEnterForeground:(NSNotification*)notification
164 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions") {
165 UIApplication* application = [UIApplication sharedApplication];
166 #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
167 if (_debugBackgroundTask != UIBackgroundTaskInvalid) {
168 [application endBackgroundTask:_debugBackgroundTask];
169 _debugBackgroundTask = UIBackgroundTaskInvalid;
172 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
176 if ([delegate respondsToSelector:
@selector(applicationWillEnterForeground:)]) {
182 - (void)handleWillResignActive:(NSNotification*)notification
183 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions") {
184 UIApplication* application = [UIApplication sharedApplication];
185 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
189 if ([delegate respondsToSelector:
@selector(applicationWillResignActive:)]) {
195 - (void)handleDidBecomeActive:(NSNotification*)notification
196 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions") {
197 UIApplication* application = [UIApplication sharedApplication];
198 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
202 if ([delegate respondsToSelector:
@selector(applicationDidBecomeActive:)]) {
208 - (void)handleWillTerminate:(NSNotification*)notification
209 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in app extensions") {
210 UIApplication* application = [UIApplication sharedApplication];
211 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
215 if ([delegate respondsToSelector:
@selector(applicationWillTerminate:)]) {
221 #pragma GCC diagnostic push
222 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
223 - (void)application:(UIApplication*)application
224 didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
225 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
229 if ([delegate respondsToSelector:_cmd]) {
234 #pragma GCC diagnostic pop
236 - (void)application:(UIApplication*)application
237 didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
238 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
242 if ([delegate respondsToSelector:_cmd]) {
249 - (void)application:(UIApplication*)application
250 didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
251 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
255 if ([delegate respondsToSelector:_cmd]) {
261 - (void)application:(UIApplication*)application
262 didReceiveRemoteNotification:(NSDictionary*)userInfo
263 fetchCompletionHandler:(
void (^)(UIBackgroundFetchResult result))completionHandler {
264 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
268 if ([delegate respondsToSelector:_cmd]) {
269 if ([delegate application:application
270 didReceiveRemoteNotification:userInfo
271 fetchCompletionHandler:completionHandler]) {
278 #pragma GCC diagnostic push
279 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
280 - (void)application:(UIApplication*)application
281 didReceiveLocalNotification:(UILocalNotification*)notification {
282 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
286 if ([delegate respondsToSelector:_cmd]) {
291 #pragma GCC diagnostic pop
293 - (void)userNotificationCenter:(UNUserNotificationCenter*)center
294 willPresentNotification:(UNNotification*)notification
295 withCompletionHandler:
296 (
void (^)(UNNotificationPresentationOptions options))completionHandler {
297 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
298 if ([delegate respondsToSelector:_cmd]) {
299 [delegate userNotificationCenter:center
300 willPresentNotification:notification
301 withCompletionHandler:completionHandler];
306 - (void)userNotificationCenter:(UNUserNotificationCenter*)center
307 didReceiveNotificationResponse:(UNNotificationResponse*)response
308 withCompletionHandler:(
void (^)(
void))completionHandler {
309 for (id<FlutterApplicationLifeCycleDelegate> delegate in
_delegates) {
310 if ([delegate respondsToSelector:_cmd]) {
311 [delegate userNotificationCenter:center
312 didReceiveNotificationResponse:response
313 withCompletionHandler:completionHandler];
318 - (BOOL)application:(UIApplication*)application
320 options:(NSDictionary<UIApplicationOpenURLOptionsKey,
id>*)options {
321 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
325 if ([delegate respondsToSelector:_cmd]) {
326 if ([delegate application:application openURL:url options:options]) {
334 - (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
335 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
339 if ([delegate respondsToSelector:_cmd]) {
340 if ([delegate application:application handleOpenURL:url]) {
348 - (BOOL)application:(UIApplication*)application
350 sourceApplication:(NSString*)sourceApplication
351 annotation:(
id)annotation {
352 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
356 if ([delegate respondsToSelector:_cmd]) {
357 if ([delegate application:application
359 sourceApplication:sourceApplication
360 annotation:annotation]) {
368 - (void)application:(UIApplication*)application
369 performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
370 completionHandler:(
void (^)(BOOL succeeded))completionHandler {
371 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
375 if ([delegate respondsToSelector:_cmd]) {
376 if ([delegate application:application
377 performActionForShortcutItem:shortcutItem
378 completionHandler:completionHandler]) {
385 - (BOOL)application:(UIApplication*)application
386 handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
387 completionHandler:(nonnull
void (^)())completionHandler {
388 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
392 if ([delegate respondsToSelector:_cmd]) {
393 if ([delegate application:application
394 handleEventsForBackgroundURLSession:identifier
395 completionHandler:completionHandler]) {
403 - (BOOL)application:(UIApplication*)application
404 performFetchWithCompletionHandler:(
void (^)(UIBackgroundFetchResult result))completionHandler {
405 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
409 if ([delegate respondsToSelector:_cmd]) {
410 if ([delegate application:application performFetchWithCompletionHandler:completionHandler]) {
418 - (BOOL)application:(UIApplication*)application
419 continueUserActivity:(NSUserActivity*)userActivity
420 restorationHandler:(
void (^)(NSArray*))restorationHandler {
421 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
425 if ([delegate respondsToSelector:_cmd]) {
426 if ([delegate application:application
427 continueUserActivity:userActivity
428 restorationHandler:restorationHandler]) {
static const SEL kSelectorsHandledByPlugins[]
NSPointerArray * _delegates
static FLUTTER_ASSERT_ARC const char * kCallbackCacheSubDir
void setCachePath:(NSString *path)
void application:didFailToRegisterForRemoteNotificationsWithError:(UIApplication *application,[didFailToRegisterForRemoteNotificationsWithError] NSError *error)
void application:didReceiveLocalNotification:(UIApplication *application,[didReceiveLocalNotification] "See -[UIApplicationDelegate application:didReceiveLocalNotification:] deprecation", ios(4.0, 10.0) API_DEPRECATED)
void applicationDidBecomeActive:(UIApplication *application)
void application:didRegisterForRemoteNotificationsWithDeviceToken:(UIApplication *application,[didRegisterForRemoteNotificationsWithDeviceToken] NSData *deviceToken)
void applicationWillTerminate:(UIApplication *application)
void application:didRegisterUserNotificationSettings:(UIApplication *application,[didRegisterUserNotificationSettings] "See -[UIApplicationDelegate application:didRegisterUserNotificationSettings:] deprecation", ios(8.0, 10.0) API_DEPRECATED)
void applicationDidEnterBackground:(UIApplication *application)
void applicationWillEnterForeground:(UIApplication *application)
void applicationWillResignActive:(UIApplication *application)