From 87a38bda25566b0e1da9aefbe2b90d38e2cf07d5 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Thu, 26 Sep 2024 17:44:29 -0700 Subject: [PATCH 1/4] iOS: Migrate FlutterAppDelegate to ARC Migrates the FlutterAppDelegate.mm translation unit to be compiled with the `-fobjc-arc` compiler flag. Issue: https://github.com/flutter/flutter/issues/137801 --- shell/platform/darwin/ios/BUILD.gn | 2 +- .../darwin/ios/framework/Source/FlutterAppDelegate.mm | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index 7b821c2d9429c..62b8f60450ceb 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -59,6 +59,7 @@ source_set("flutter_framework_source_arc") { public_configs = [ "//flutter:config" ] sources = [ + "framework/Source/FlutterAppDelegate.mm", "framework/Source/FlutterCallbackCache.mm", "framework/Source/FlutterCallbackCache_Internal.h", "framework/Source/FlutterChannelKeyResponder.h", @@ -179,7 +180,6 @@ source_set("flutter_framework_source") { # iOS embedder is migrating to ARC. # New files are highly encouraged to be in ARC. # To add new files in ARC, add them to the `flutter_framework_source_arc` target. - "framework/Source/FlutterAppDelegate.mm", "framework/Source/FlutterEngine.mm", "framework/Source/FlutterEngineGroup.mm", "framework/Source/FlutterEngine_Internal.h", diff --git a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm index 6f784e7de374f..0f086827bb26a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm @@ -31,13 +31,6 @@ - (instancetype)init { return self; } -- (void)dealloc { - [_lifeCycleDelegate release]; - [_rootFlutterViewControllerGetter release]; - [_window release]; - [super dealloc]; -} - - (BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions { return [_lifeCycleDelegate application:application willFinishLaunchingWithOptions:launchOptions]; @@ -286,7 +279,7 @@ - (id)forwardingTargetForSelector:(SEL)aSelector { - (void)logCapabilityConfigurationWarningIfNeeded:(SEL)selector { NSArray* backgroundModesArray = [[NSBundle mainBundle] objectForInfoDictionaryKey:kUIBackgroundMode]; - NSSet* backgroundModesSet = [[[NSSet alloc] initWithArray:backgroundModesArray] autorelease]; + NSSet* backgroundModesSet = [[NSSet alloc] initWithArray:backgroundModesArray]; if (selector == @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)) { if (![backgroundModesSet containsObject:kRemoteNotificationCapabitiliy]) { NSLog( From 5dd6cfec261e9b2a0bcb10fce8c64e4f81ad4e89 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Fri, 27 Sep 2024 12:14:13 -0700 Subject: [PATCH 2/4] Add ARC check macro --- .../platform/darwin/ios/framework/Source/FlutterAppDelegate.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm index 0f086827bb26a..33f75a5c67b1a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm @@ -11,6 +11,8 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate_internal.h" +FLUTTER_ASSERT_ARC + static NSString* const kUIBackgroundMode = @"UIBackgroundModes"; static NSString* const kRemoteNotificationCapabitiliy = @"remote-notification"; static NSString* const kBackgroundFetchCapatibility = @"fetch"; From c353189a8a274179b0e73969d68ad371da5f6852 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Fri, 27 Sep 2024 13:07:45 -0700 Subject: [PATCH 3/4] Make lifecycle delegate a property --- .../darwin/ios/framework/Source/FlutterAppDelegate.mm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm index 33f75a5c67b1a..399c40d5d570a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm @@ -20,11 +20,10 @@ @interface FlutterAppDelegate () @property(nonatomic, copy) FlutterViewController* (^rootFlutterViewControllerGetter)(void); +@property(nonatomic, strong) FlutterPluginAppLifeCycleDelegate* lifeCycleDelegate; @end -@implementation FlutterAppDelegate { - FlutterPluginAppLifeCycleDelegate* _lifeCycleDelegate; -} +@implementation FlutterAppDelegate - (instancetype)init { if (self = [super init]) { From 5ff70d02829da6c5b20b3e34bb94858fa9b7f658 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Fri, 27 Sep 2024 14:54:10 -0700 Subject: [PATCH 4/4] Use getter syntax rather than referencing ivar directly Except in the initialiser, where `self` is not yet fully initialised. In this case, it's a simple property so this really makes no real difference, but best practices etc. --- .../framework/Source/FlutterAppDelegate.mm | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm index 399c40d5d570a..1831cd34d2dd1 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm @@ -34,12 +34,14 @@ - (instancetype)init { - (BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - return [_lifeCycleDelegate application:application willFinishLaunchingWithOptions:launchOptions]; + return [self.lifeCycleDelegate application:application + willFinishLaunchingWithOptions:launchOptions]; } - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - return [_lifeCycleDelegate application:application didFinishLaunchingWithOptions:launchOptions]; + return [self.lifeCycleDelegate application:application + didFinishLaunchingWithOptions:launchOptions]; } // Returns the key window's rootViewController, if it's a FlutterViewController. @@ -79,20 +81,20 @@ - (void)applicationWillTerminate:(UIApplication*)application { #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - (void)application:(UIApplication*)application didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings { - [_lifeCycleDelegate application:application + [self.lifeCycleDelegate application:application didRegisterUserNotificationSettings:notificationSettings]; } #pragma GCC diagnostic pop - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken { - [_lifeCycleDelegate application:application + [self.lifeCycleDelegate application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } - (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error { - [_lifeCycleDelegate application:application + [self.lifeCycleDelegate application:application didFailToRegisterForRemoteNotificationsWithError:error]; } @@ -100,7 +102,7 @@ - (void)application:(UIApplication*)application #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - (void)application:(UIApplication*)application didReceiveLocalNotification:(UILocalNotification*)notification { - [_lifeCycleDelegate application:application didReceiveLocalNotification:notification]; + [self.lifeCycleDelegate application:application didReceiveLocalNotification:notification]; } #pragma GCC diagnostic pop @@ -108,10 +110,10 @@ - (void)userNotificationCenter:(UNUserNotificationCenter*)center willPresentNotification:(UNNotification*)notification withCompletionHandler: (void (^)(UNNotificationPresentationOptions options))completionHandler { - if ([_lifeCycleDelegate respondsToSelector:_cmd]) { - [_lifeCycleDelegate userNotificationCenter:center - willPresentNotification:notification - withCompletionHandler:completionHandler]; + if ([self.lifeCycleDelegate respondsToSelector:_cmd]) { + [self.lifeCycleDelegate userNotificationCenter:center + willPresentNotification:notification + withCompletionHandler:completionHandler]; } } @@ -121,10 +123,10 @@ - (void)userNotificationCenter:(UNUserNotificationCenter*)center - (void)userNotificationCenter:(UNUserNotificationCenter*)center didReceiveNotificationResponse:(UNNotificationResponse*)response withCompletionHandler:(void (^)(void))completionHandler { - if ([_lifeCycleDelegate respondsToSelector:_cmd]) { - [_lifeCycleDelegate userNotificationCenter:center - didReceiveNotificationResponse:response - withCompletionHandler:completionHandler]; + if ([self.lifeCycleDelegate respondsToSelector:_cmd]) { + [self.lifeCycleDelegate userNotificationCenter:center + didReceiveNotificationResponse:response + withCompletionHandler:completionHandler]; } } @@ -139,7 +141,7 @@ - (BOOL)isFlutterDeepLinkingEnabled { - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url options:(NSDictionary*)options { - if ([_lifeCycleDelegate application:application openURL:url options:options]) { + if ([self.lifeCycleDelegate application:application openURL:url options:options]) { return YES; } @@ -172,31 +174,31 @@ - (BOOL)handleOpenURL:(NSURL*)url } - (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url { - return [_lifeCycleDelegate application:application handleOpenURL:url]; + return [self.lifeCycleDelegate application:application handleOpenURL:url]; } - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation { - return [_lifeCycleDelegate application:application - openURL:url - sourceApplication:sourceApplication - annotation:annotation]; + return [self.lifeCycleDelegate application:application + openURL:url + sourceApplication:sourceApplication + annotation:annotation]; } - (void)application:(UIApplication*)application performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler { - [_lifeCycleDelegate application:application - performActionForShortcutItem:shortcutItem - completionHandler:completionHandler]; + [self.lifeCycleDelegate application:application + performActionForShortcutItem:shortcutItem + completionHandler:completionHandler]; } - (void)application:(UIApplication*)application handleEventsForBackgroundURLSession:(nonnull NSString*)identifier completionHandler:(nonnull void (^)())completionHandler { - [_lifeCycleDelegate application:application + [self.lifeCycleDelegate application:application handleEventsForBackgroundURLSession:identifier completionHandler:completionHandler]; } @@ -207,9 +209,9 @@ - (BOOL)application:(UIApplication*)application restorationHandler: (void (^)(NSArray>* __nullable restorableObjects)) restorationHandler { - if ([_lifeCycleDelegate application:application - continueUserActivity:userActivity - restorationHandler:restorationHandler]) { + if ([self.lifeCycleDelegate application:application + continueUserActivity:userActivity + restorationHandler:restorationHandler]) { return YES; } @@ -245,30 +247,30 @@ - (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey { #pragma mark - Selectors handling - (void)addApplicationLifeCycleDelegate:(NSObject*)delegate { - [_lifeCycleDelegate addDelegate:delegate]; + [self.lifeCycleDelegate addDelegate:delegate]; } #pragma mark - UIApplicationDelegate method dynamic implementation - (BOOL)respondsToSelector:(SEL)selector { - if ([_lifeCycleDelegate isSelectorAddedDynamically:selector]) { + if ([self.lifeCycleDelegate isSelectorAddedDynamically:selector]) { return [self delegateRespondsSelectorToPlugins:selector]; } return [super respondsToSelector:selector]; } - (BOOL)delegateRespondsSelectorToPlugins:(SEL)selector { - if ([_lifeCycleDelegate hasPluginThatRespondsToSelector:selector]) { - return [_lifeCycleDelegate respondsToSelector:selector]; + if ([self.lifeCycleDelegate hasPluginThatRespondsToSelector:selector]) { + return [self.lifeCycleDelegate respondsToSelector:selector]; } else { return NO; } } - (id)forwardingTargetForSelector:(SEL)aSelector { - if ([_lifeCycleDelegate isSelectorAddedDynamically:aSelector]) { + if ([self.lifeCycleDelegate isSelectorAddedDynamically:aSelector]) { [self logCapabilityConfigurationWarningIfNeeded:aSelector]; - return _lifeCycleDelegate; + return self.lifeCycleDelegate; } return [super forwardingTargetForSelector:aSelector]; }