5#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h"
7#include "flutter/fml/logging.h"
8#include "flutter/fml/paths.h"
9#include "flutter/lib/ui/plugins/callback_cache.h"
10#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterCallbackCache_Internal.h"
17 @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:),
18 @selector(application:performFetchWithCompletionHandler:)};
21- (void)handleDidEnterBackground:(NSNotification*)notification
23- (void)handleWillEnterForeground:(NSNotification*)notification
25- (void)handleWillResignActive:(NSNotification*)notification
27- (void)handleDidBecomeActive:(NSNotification*)notification
29- (void)handleWillTerminate:(NSNotification*)notification
34 UIBackgroundTaskIdentifier _debugBackgroundTask;
40- (void)addObserverFor:(NSString*)name selector:(
SEL)selector {
41 [[NSNotificationCenter defaultCenter] addObserver:self selector:selector name:name object:nil];
48#if not APPLICATION_EXTENSION_API_ONLY
49 [
self addObserverFor:UIApplicationDidEnterBackgroundNotification
50 selector:@selector(handleDidEnterBackground:)];
51 [
self addObserverFor:UIApplicationWillEnterForegroundNotification
52 selector:@selector(handleWillEnterForeground:)];
53 [
self addObserverFor:UIApplicationWillResignActiveNotification
54 selector:@selector(handleWillResignActive:)];
55 [
self addObserverFor:UIApplicationDidBecomeActiveNotification
56 selector:@selector(handleDidBecomeActive:)];
57 [
self addObserverFor:UIApplicationWillTerminateNotification
58 selector:@selector(handleWillTerminate:)];
60 _delegates = [NSPointerArray weakObjectsPointerArray];
61 _debugBackgroundTask = UIBackgroundTaskInvalid;
66static BOOL IsPowerOfTwo(NSUInteger
x) {
67 return x != 0 && (
x & (
x - 1)) == 0;
70- (
BOOL)isSelectorAddedDynamically:(
SEL)selector {
72 if (selector == aSelector) {
79- (
BOOL)hasPluginThatRespondsToSelector:(
SEL)selector {
80 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in [
_delegates allObjects]) {
84 if ([delegate respondsToSelector:selector]) {
92 [_delegates addPointer:(__bridge void*)delegate];
98- (
BOOL)application:(UIApplication*)application
99 didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
100 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in [
_delegates allObjects]) {
104 if ([delegate respondsToSelector:_cmd]) {
105 if (![delegate application:application didFinishLaunchingWithOptions:launchOptions]) {
113- (
BOOL)application:(UIApplication*)application
114 willFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
116 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in [
_delegates allObjects]) {
120 if ([delegate respondsToSelector:_cmd]) {
121 if (![delegate application:application willFinishLaunchingWithOptions:launchOptions]) {
129- (void)handleDidEnterBackground:(NSNotification*)notification
130 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in
app extensions") {
131 UIApplication* application = [UIApplication sharedApplication];
132#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
138 _debugBackgroundTask = [application
139 beginBackgroundTaskWithName:@"Flutter debug task"
141 if (_debugBackgroundTask != UIBackgroundTaskInvalid) {
142 [application endBackgroundTask:_debugBackgroundTask];
143 _debugBackgroundTask = UIBackgroundTaskInvalid;
146 << "\nThe OS has terminated the Flutter debug connection for being "
147 "inactive in the background for too long.\n\n"
148 "There are no errors with your Flutter application.\n\n"
149 "To reconnect, launch your application again via 'flutter run'";
152 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
156 if ([delegate respondsToSelector:
@selector(applicationDidEnterBackground:)]) {
162- (void)handleWillEnterForeground:(NSNotification*)notification
163 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in
app extensions") {
164 UIApplication* application = [UIApplication sharedApplication];
165#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
166 if (_debugBackgroundTask != UIBackgroundTaskInvalid) {
167 [application endBackgroundTask:_debugBackgroundTask];
168 _debugBackgroundTask = UIBackgroundTaskInvalid;
171 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
175 if ([delegate respondsToSelector:
@selector(applicationWillEnterForeground:)]) {
181- (void)handleWillResignActive:(NSNotification*)notification
182 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in
app extensions") {
183 UIApplication* application = [UIApplication sharedApplication];
184 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
188 if ([delegate respondsToSelector:
@selector(applicationWillResignActive:)]) {
194- (void)handleDidBecomeActive:(NSNotification*)notification
195 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in
app extensions") {
196 UIApplication* application = [UIApplication sharedApplication];
197 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
201 if ([delegate respondsToSelector:
@selector(applicationDidBecomeActive:)]) {
207- (void)handleWillTerminate:(NSNotification*)notification
208 NS_EXTENSION_UNAVAILABLE_IOS("Disallowed in
app extensions") {
209 UIApplication* application = [UIApplication sharedApplication];
210 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
214 if ([delegate respondsToSelector:
@selector(applicationWillTerminate:)]) {
220#pragma GCC diagnostic push
221#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
222- (void)application:(UIApplication*)application
223 didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
224 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
228 if ([delegate respondsToSelector:_cmd]) {
233#pragma GCC diagnostic pop
235- (void)application:(UIApplication*)application
236 didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
237 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
241 if ([delegate respondsToSelector:_cmd]) {
248- (void)application:(UIApplication*)application
249 didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
250 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
254 if ([delegate respondsToSelector:_cmd]) {
260- (void)application:(UIApplication*)application
261 didReceiveRemoteNotification:(NSDictionary*)userInfo
262 fetchCompletionHandler:(
void (^)(UIBackgroundFetchResult
result))completionHandler {
263 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
267 if ([delegate respondsToSelector:_cmd]) {
268 if ([delegate application:application
269 didReceiveRemoteNotification:userInfo
270 fetchCompletionHandler:completionHandler]) {
277#pragma GCC diagnostic push
278#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
279- (void)application:(UIApplication*)application
280 didReceiveLocalNotification:(UILocalNotification*)notification {
281 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
285 if ([delegate respondsToSelector:_cmd]) {
290#pragma GCC diagnostic pop
292- (void)userNotificationCenter:(UNUserNotificationCenter*)center
293 willPresentNotification:(UNNotification*)notification
294 withCompletionHandler:
295 (
void (^)(UNNotificationPresentationOptions
options))completionHandler {
296 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
297 if ([delegate respondsToSelector:_cmd]) {
298 [delegate userNotificationCenter:center
299 willPresentNotification:notification
300 withCompletionHandler:completionHandler];
305- (void)userNotificationCenter:(UNUserNotificationCenter*)center
306 didReceiveNotificationResponse:(UNNotificationResponse*)response
307 withCompletionHandler:(
void (^)(
void))completionHandler {
308 for (id<FlutterApplicationLifeCycleDelegate> delegate in
_delegates) {
309 if ([delegate respondsToSelector:_cmd]) {
310 [delegate userNotificationCenter:center
311 didReceiveNotificationResponse:response
312 withCompletionHandler:completionHandler];
317- (
BOOL)application:(UIApplication*)application
319 options:(NSDictionary<UIApplicationOpenURLOptionsKey,
id>*)options {
320 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
324 if ([delegate respondsToSelector:_cmd]) {
325 if ([delegate application:application openURL:url
options:
options]) {
333- (
BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
334 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
338 if ([delegate respondsToSelector:_cmd]) {
339 if ([delegate application:application handleOpenURL:url]) {
347- (
BOOL)application:(UIApplication*)application
349 sourceApplication:(NSString*)sourceApplication
350 annotation:(
id)annotation {
351 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
355 if ([delegate respondsToSelector:_cmd]) {
356 if ([delegate application:application
358 sourceApplication:sourceApplication
359 annotation:annotation]) {
367- (void)application:(UIApplication*)application
368 performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
369 completionHandler:(
void (^)(
BOOL succeeded))completionHandler {
370 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
374 if ([delegate respondsToSelector:_cmd]) {
375 if ([delegate application:application
376 performActionForShortcutItem:shortcutItem
377 completionHandler:completionHandler]) {
384- (
BOOL)application:(UIApplication*)application
385 handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
386 completionHandler:(nonnull
void (^)())completionHandler {
387 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
391 if ([delegate respondsToSelector:_cmd]) {
392 if ([delegate application:application
393 handleEventsForBackgroundURLSession:
identifier
394 completionHandler:completionHandler]) {
402- (
BOOL)application:(UIApplication*)application
403 performFetchWithCompletionHandler:(
void (^)(UIBackgroundFetchResult
result))completionHandler {
404 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
408 if ([delegate respondsToSelector:_cmd]) {
409 if ([delegate application:application performFetchWithCompletionHandler:completionHandler]) {
417- (
BOOL)application:(UIApplication*)application
418 continueUserActivity:(NSUserActivity*)userActivity
419 restorationHandler:(
void (^)(NSArray*))restorationHandler {
420 for (NSObject<FlutterApplicationLifeCycleDelegate>* delegate in
_delegates) {
424 if ([delegate respondsToSelector:_cmd]) {
425 if ([delegate application:application
426 continueUserActivity:userActivity
427 restorationHandler:restorationHandler]) {
static const SEL kSelectorsHandledByPlugins[]
NSPointerArray * _delegates
static FLUTTER_ASSERT_ARC const char * kCallbackCacheSubDir
static void LoadCacheFromDisk()
static SkString identifier(const FontFamilyDesc &family, const FontDesc &font)
void setCachePath:(NSString *path)
std::string JoinPaths(std::initializer_list< std::string > components)
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)