Revert "Delegate AppDelegate life-cycle callbacks to plugins via separate object (#5173)" (flutter/engine#5294)

This reverts commit f8d59eeabc as it broke
mac engine build bot.
This commit is contained in:
Alexander Aprelev
2018-05-17 14:11:12 -07:00
committed by GitHub
parent 6ef8fbd2a3
commit bc4d335137
9 changed files with 221 additions and 566 deletions

View File

@@ -22,7 +22,6 @@ _flutter_framework_headers = [
"framework/Headers/FlutterMacros.h",
"framework/Headers/FlutterNavigationController.h",
"framework/Headers/FlutterPlugin.h",
"framework/Headers/FlutterPluginAppLifeCycleDelegate.h",
"framework/Headers/FlutterTexture.h",
"framework/Headers/FlutterViewController.h",
]
@@ -44,7 +43,6 @@ shared_library("create_flutter_framework_dylib") {
"framework/Source/FlutterNavigationController.mm",
"framework/Source/FlutterPlatformPlugin.h",
"framework/Source/FlutterPlatformPlugin.mm",
"framework/Source/FlutterPluginAppLifeCycleDelegate.mm",
"framework/Source/FlutterStandardCodec.mm",
"framework/Source/FlutterStandardCodec_Internal.h",
"framework/Source/FlutterTextInputDelegate.h",

View File

@@ -43,7 +43,6 @@
#include "FlutterMacros.h"
#include "FlutterNavigationController.h"
#include "FlutterPlugin.h"
#include "FlutterPluginAppLifeCycleDelegate.h"
#include "FlutterTexture.h"
#include "FlutterViewController.h"

View File

@@ -24,10 +24,22 @@
* code as necessary from FlutterAppDelegate.mm.
*/
FLUTTER_EXPORT
@interface FlutterAppDelegate : UIResponder<UIApplicationDelegate, FlutterPluginRegistry, FlutterAppLifeCycleProvider>
@interface FlutterAppDelegate : UIResponder<UIApplicationDelegate, FlutterPluginRegistry>
@property(strong, nonatomic) UIWindow* window;
// Can be overriden by subclasses to provide a custom FlutterBinaryMessenger,
// typically a FlutterViewController, for plugin interop.
//
// Defaults to window's rootViewController.
- (NSObject<FlutterBinaryMessenger>*)binaryMessenger;
// Can be overriden by subclasses to provide a custom FlutterTextureRegistry,
// typically a FlutterViewController, for plugin interop.
//
// Defaults to window's rootViewController.
- (NSObject<FlutterTextureRegistry>*)textures;
@end
#endif // FLUTTER_FLUTTERDARTPROJECT_H_

View File

@@ -253,14 +253,6 @@ NS_ASSUME_NONNULL_BEGIN
- (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey;
@end
/**
Implement this in the `UIAppDelegate` of your app to enable Flutter plugins to register themselves to the application
life cycle events.
*/
@protocol FlutterAppLifeCycleProvider
- (void)addApplicationLifeCycleDelegate:(NSObject<FlutterPlugin>*)delegate;
@end
NS_ASSUME_NONNULL_END;
#endif // FLUTTER_FLUTTERPLUGIN_H_

View File

@@ -1,135 +0,0 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_
#define FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_
#include "FlutterPlugin.h"
NS_ASSUME_NONNULL_BEGIN
/**
Propagates `UIAppDelegate` callbacks to registered plugins.
*/
FLUTTER_EXPORT
@interface FlutterPluginAppLifeCycleDelegate : NSObject
/**
Registers `delegate` to receive life cycle callbacks via this FlutterPluginAppLifecycleDelegate as long as it is alive.
`delegate` will only referenced weakly.
*/
- (void)addDelegate:(NSObject<FlutterPlugin>*)delegate;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
- Returns: `NO` if any plugin vetoes application launch.
*/
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationDidBecomeActive:(UIApplication*)application;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillResignActive:(UIApplication*)application;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationDidEnterBackground:(UIApplication*)application;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillEnterForeground:(UIApplication*)application;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillTerminate:(UIApplication*)application;
/**
Called if this plugin has been registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication*)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication*)application
didReceiveRemoteNotification:(NSDictionary*)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until some plugin handles
the request.
- Returns: `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until some plugin handles
the request.
- Returns: `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until some plugin handles
the request.
- Returns: `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication*)application
performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
completionHandler:(void (^)(BOOL succeeded))completionHandler
API_AVAILABLE(ios(9.0));
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until some plugin handles
the request.
- Returns: `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
completionHandler:(nonnull void (^)())completionHandler;
/**
Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until some plugin handles
the request.
- Returns: `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
@end
NS_ASSUME_NONNULL_END
#endif // FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_

View File

@@ -11,11 +11,10 @@
#include "FlutterBinaryMessenger.h"
#include "FlutterDartProject.h"
#include "FlutterMacros.h"
#include "FlutterPlugin.h"
#include "FlutterTexture.h"
FLUTTER_EXPORT
@interface FlutterViewController : UIViewController<FlutterBinaryMessenger, FlutterTextureRegistry, FlutterPluginRegistry>
@interface FlutterViewController : UIViewController<FlutterBinaryMessenger, FlutterTextureRegistry>
- (instancetype)initWithProject:(FlutterDartProject*)project
nibName:(NSString*)nibNameOrNil
@@ -50,8 +49,6 @@ FLUTTER_EXPORT
*/
- (void)setInitialRoute:(NSString*)route;
- (id<FlutterPluginRegistry>)pluginRegistry;
@end
#endif // FLUTTER_FLUTTERVIEWCONTROLLER_H_

View File

@@ -3,28 +3,46 @@
// found in the LICENSE file.
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h"
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h"
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
#include "lib/fxl/logging.h"
@interface FlutterAppDelegate ()
@property(readonly, nonatomic) NSMutableArray* pluginDelegates;
@property(readonly, nonatomic) NSMutableDictionary* pluginPublications;
@end
@interface FlutterAppDelegateRegistrar : NSObject <FlutterPluginRegistrar>
- (instancetype)initWithPlugin:(NSString*)pluginKey appDelegate:(FlutterAppDelegate*)delegate;
@end
@implementation FlutterAppDelegate {
FlutterPluginAppLifeCycleDelegate* _lifeCycleDelegate;
UIBackgroundTaskIdentifier _debugBackgroundTask;
}
- (instancetype)init {
if (self = [super init]) {
_lifeCycleDelegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
_pluginDelegates = [NSMutableArray new];
_pluginPublications = [NSMutableDictionary new];
}
return self;
}
- (void)dealloc {
[_lifeCycleDelegate release];
[_pluginDelegates release];
[_pluginPublications release];
[super dealloc];
}
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
return [_lifeCycleDelegate application:application didFinishLaunchingWithOptions:launchOptions];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
if (![plugin application:application didFinishLaunchingWithOptions:launchOptions]) {
return NO;
}
}
}
return YES;
}
// Returns the key window's rootViewController, if it's a FlutterViewController.
@@ -47,118 +65,257 @@
}
- (void)applicationDidEnterBackground:(UIApplication*)application {
[_lifeCycleDelegate applicationDidEnterBackground:application];
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
// The following keeps the Flutter session alive when the device screen locks
// in debug mode. It allows continued use of features like hot reload and
// taking screenshots once the device unlocks again.
//
// Note the name is not an identifier and multiple instances can exist.
_debugBackgroundTask = [application
beginBackgroundTaskWithName:@"Flutter debug task"
expirationHandler:^{
FXL_LOG(WARNING)
<< "\nThe OS has terminated the Flutter debug connection for being "
"inactive in the background for too long.\n\n"
"There are no errors with your Flutter application.\n\n"
"To reconnect, launch your application again via 'flutter run'";
}];
#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationDidEnterBackground:application];
}
}
}
- (void)applicationWillEnterForeground:(UIApplication*)application {
[_lifeCycleDelegate applicationWillEnterForeground:application];
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
[application endBackgroundTask:_debugBackgroundTask];
#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationWillEnterForeground:application];
}
}
}
- (void)applicationWillResignActive:(UIApplication*)application {
[_lifeCycleDelegate applicationWillResignActive:application];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationWillResignActive:application];
}
}
}
- (void)applicationDidBecomeActive:(UIApplication*)application {
[_lifeCycleDelegate applicationDidBecomeActive:application];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationDidBecomeActive:application];
}
}
}
- (void)applicationWillTerminate:(UIApplication*)application {
[_lifeCycleDelegate applicationWillTerminate:application];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationWillTerminate:application];
}
}
}
- (void)application:(UIApplication*)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
[_lifeCycleDelegate application:application
didRegisterUserNotificationSettings:notificationSettings];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
[plugin application:application didRegisterUserNotificationSettings:notificationSettings];
}
}
}
- (void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
[_lifeCycleDelegate application:application
didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
[plugin application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
}
}
- (void)application:(UIApplication*)application
didReceiveRemoteNotification:(NSDictionary*)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
[_lifeCycleDelegate application:application
didReceiveRemoteNotification:userInfo
fetchCompletionHandler:completionHandler];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application
didReceiveRemoteNotification:userInfo
fetchCompletionHandler:completionHandler]) {
return;
}
}
}
}
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options {
return [_lifeCycleDelegate application:application openURL:url options:options];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application openURL:url options:options]) {
return YES;
}
}
}
return NO;
}
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
return [_lifeCycleDelegate application:application handleOpenURL:url];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application handleOpenURL:url]) {
return YES;
}
}
}
return NO;
}
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation {
return [_lifeCycleDelegate application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation]) {
return YES;
}
}
}
return NO;
}
- (void)application:(UIApplication*)application
performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
completionHandler:(void (^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0) {
[_lifeCycleDelegate application:application
performActionForShortcutItem:shortcutItem
completionHandler:completionHandler];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application
performActionForShortcutItem:shortcutItem
completionHandler:completionHandler]) {
return;
}
}
}
}
- (void)application:(UIApplication*)application
handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
completionHandler:(nonnull void (^)())completionHandler {
[_lifeCycleDelegate application:application
handleEventsForBackgroundURLSession:identifier
completionHandler:completionHandler];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application
handleEventsForBackgroundURLSession:identifier
completionHandler:completionHandler]) {
return;
}
}
}
}
- (void)application:(UIApplication*)application
performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
[_lifeCycleDelegate application:application performFetchWithCompletionHandler:completionHandler];
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application performFetchWithCompletionHandler:completionHandler]) {
return;
}
}
}
}
#pragma mark - FlutterPluginRegistry methods. All delegating to the rootViewController
- (NSObject<FlutterPluginRegistrar>*)registrarForPlugin:(NSString*)pluginKey {
// TODO(xster): move when doing https://github.com/flutter/flutter/issues/3671.
- (NSObject<FlutterBinaryMessenger>*)binaryMessenger {
UIViewController* rootViewController = _window.rootViewController;
if ([rootViewController isKindOfClass:[FlutterViewController class]]) {
return
[[(FlutterViewController*)rootViewController pluginRegistry] registrarForPlugin:pluginKey];
if ([rootViewController conformsToProtocol:@protocol(FlutterBinaryMessenger)]) {
return (NSObject<FlutterBinaryMessenger>*)rootViewController;
}
return nil;
}
- (NSObject<FlutterTextureRegistry>*)textures {
UIViewController* rootViewController = _window.rootViewController;
if ([rootViewController conformsToProtocol:@protocol(FlutterTextureRegistry)]) {
return (NSObject<FlutterTextureRegistry>*)rootViewController;
}
return nil;
}
- (NSObject<FlutterPluginRegistrar>*)registrarForPlugin:(NSString*)pluginKey {
NSAssert(self.pluginPublications[pluginKey] == nil, @"Duplicate plugin key: %@", pluginKey);
self.pluginPublications[pluginKey] = [NSNull null];
return
[[[FlutterAppDelegateRegistrar alloc] initWithPlugin:pluginKey appDelegate:self] autorelease];
}
- (BOOL)hasPlugin:(NSString*)pluginKey {
UIViewController* rootViewController = _window.rootViewController;
if ([rootViewController isKindOfClass:[FlutterViewController class]]) {
return [[(FlutterViewController*)rootViewController pluginRegistry] hasPlugin:pluginKey];
}
return nil;
return _pluginPublications[pluginKey] != nil;
}
- (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey {
UIViewController* rootViewController = _window.rootViewController;
if ([rootViewController isKindOfClass:[FlutterViewController class]]) {
return [[(FlutterViewController*)rootViewController pluginRegistry]
valuePublishedByPlugin:pluginKey];
}
return nil;
return _pluginPublications[pluginKey];
}
@end
@implementation FlutterAppDelegateRegistrar {
NSString* _pluginKey;
FlutterAppDelegate* _appDelegate;
}
#pragma mark - FlutterAppLifeCycleProvider methods
- (instancetype)initWithPlugin:(NSString*)pluginKey appDelegate:(FlutterAppDelegate*)appDelegate {
self = [super init];
NSAssert(self, @"Super init cannot be nil");
_pluginKey = [pluginKey retain];
_appDelegate = [appDelegate retain];
return self;
}
- (void)addApplicationLifeCycleDelegate:(NSObject<FlutterPlugin>*)delegate {
[_lifeCycleDelegate addDelegate:delegate];
- (void)dealloc {
[_pluginKey release];
[_appDelegate release];
[super dealloc];
}
- (NSObject<FlutterBinaryMessenger>*)messenger {
return [_appDelegate binaryMessenger];
}
- (NSObject<FlutterTextureRegistry>*)textures {
return [_appDelegate textures];
}
- (void)publish:(NSObject*)value {
_appDelegate.pluginPublications[_pluginKey] = value;
}
- (void)addMethodCallDelegate:(NSObject<FlutterPlugin>*)delegate
channel:(FlutterMethodChannel*)channel {
[channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
[delegate handleMethodCall:call result:result];
}];
}
- (void)addApplicationDelegate:(NSObject<FlutterPlugin>*)delegate {
[_appDelegate.pluginDelegates addObject:delegate];
}
- (NSString*)lookupKeyForAsset:(NSString*)asset {
return [FlutterDartProject lookupKeyForAsset:asset];
}
- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package {
return [FlutterDartProject lookupKeyForAsset:asset fromPackage:package];
}
@end

View File

@@ -1,278 +0,0 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h"
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
#include "lib/fxl/logging.h"
@implementation FlutterPluginAppLifeCycleDelegate {
UIBackgroundTaskIdentifier _debugBackgroundTask;
// Weak references to registered plugins.
NSPointerArray* _pluginDelegates;
}
- (instancetype)init {
if (self = [super init]) {
_pluginDelegates = [[NSPointerArray weakObjectsPointerArray] retain];
}
return self;
}
- (void)dealloc {
[_pluginDelegates release];
[super dealloc];
}
static BOOL isPowerOfTwo(NSUInteger x) {
return x != 0 && (x & (x - 1)) == 0;
}
- (void)addDelegate:(NSObject<FlutterPlugin>*)delegate {
[_pluginDelegates addPointer:(__bridge void*)delegate];
if (isPowerOfTwo([_pluginDelegates count])) {
[_pluginDelegates compact];
}
}
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
for (id<FlutterPlugin> plugin in [_pluginDelegates allObjects]) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
if (![plugin application:application didFinishLaunchingWithOptions:launchOptions]) {
return NO;
}
}
}
return YES;
}
// Returns the key window's rootViewController, if it's a FlutterViewController.
// Otherwise, returns nil.
- (FlutterViewController*)rootFlutterViewController {
UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
if ([viewController isKindOfClass:[FlutterViewController class]]) {
return (FlutterViewController*)viewController;
}
return nil;
}
- (void)applicationDidEnterBackground:(UIApplication*)application {
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
// The following keeps the Flutter session alive when the device screen locks
// in debug mode. It allows continued use of features like hot reload and
// taking screenshots once the device unlocks again.
//
// Note the name is not an identifier and multiple instances can exist.
_debugBackgroundTask = [application
beginBackgroundTaskWithName:@"Flutter debug task"
expirationHandler:^{
FXL_LOG(WARNING)
<< "\nThe OS has terminated the Flutter debug connection for being "
"inactive in the background for too long.\n\n"
"There are no errors with your Flutter application.\n\n"
"To reconnect, launch your application again via 'flutter run'";
}];
#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationDidEnterBackground:application];
}
}
}
- (void)applicationWillEnterForeground:(UIApplication*)application {
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
[application endBackgroundTask:_debugBackgroundTask];
#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationWillEnterForeground:application];
}
}
}
- (void)applicationWillResignActive:(UIApplication*)application {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationWillResignActive:application];
}
}
}
- (void)applicationDidBecomeActive:(UIApplication*)application {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationDidBecomeActive:application];
}
}
}
- (void)applicationWillTerminate:(UIApplication*)application {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
[plugin applicationWillTerminate:application];
}
}
}
- (void)application:(UIApplication*)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
[plugin application:application didRegisterUserNotificationSettings:notificationSettings];
}
}
}
- (void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
[plugin application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
}
}
- (void)application:(UIApplication*)application
didReceiveRemoteNotification:(NSDictionary*)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application
didReceiveRemoteNotification:userInfo
fetchCompletionHandler:completionHandler]) {
return;
}
}
}
}
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application openURL:url options:options]) {
return YES;
}
}
}
return NO;
}
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application handleOpenURL:url]) {
return YES;
}
}
}
return NO;
}
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation]) {
return YES;
}
}
}
return NO;
}
- (void)application:(UIApplication*)application
performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
completionHandler:(void (^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0) {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application
performActionForShortcutItem:shortcutItem
completionHandler:completionHandler]) {
return;
}
}
}
}
- (BOOL)application:(UIApplication*)application
handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
completionHandler:(nonnull void (^)())completionHandler {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application
handleEventsForBackgroundURLSession:identifier
completionHandler:completionHandler]) {
return YES;
}
}
}
return NO;
}
- (BOOL)application:(UIApplication*)application
performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
for (id<FlutterPlugin> plugin in _pluginDelegates) {
if (!plugin) {
continue;
}
if ([plugin respondsToSelector:_cmd]) {
if ([plugin application:application performFetchWithCompletionHandler:completionHandler]) {
return YES;
}
}
}
return NO;
}
@end

View File

@@ -22,12 +22,6 @@
#include "flutter/shell/platform/darwin/ios/platform_view_ios.h"
@interface FlutterViewController () <FlutterTextInputDelegate>
@property(nonatomic, readonly) NSMutableDictionary* pluginPublications;
@end
@interface FlutterViewControllerRegistrar : NSObject <FlutterPluginRegistrar>
- (instancetype)initWithPlugin:(NSString*)pluginKey
flutterViewController:(FlutterViewController*)flutterViewController;
@end
@implementation FlutterViewController {
@@ -99,8 +93,6 @@
if ([self setupShell]) {
[self setupChannels];
[self setupNotificationCenterObservers];
_pluginPublications = [NSMutableDictionary new];
}
}
@@ -434,7 +426,6 @@
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_pluginPublications release];
[super dealloc];
}
@@ -980,82 +971,4 @@ constexpr CGFloat kStandardStatusBarHeight = 20.0;
return [FlutterDartProject lookupKeyForAsset:asset fromPackage:package];
}
- (id<FlutterPluginRegistry>)pluginRegistry {
return self;
}
#pragma mark - FlutterPluginRegistry
- (NSObject<FlutterPluginRegistrar>*)registrarForPlugin:(NSString*)pluginKey {
NSAssert(self.pluginPublications[pluginKey] == nil, @"Duplicate plugin key: %@", pluginKey);
self.pluginPublications[pluginKey] = [NSNull null];
return
[[FlutterViewControllerRegistrar alloc] initWithPlugin:pluginKey flutterViewController:self];
}
- (BOOL)hasPlugin:(NSString*)pluginKey {
return _pluginPublications[pluginKey] != nil;
}
- (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey {
return _pluginPublications[pluginKey];
}
@end
@implementation FlutterViewControllerRegistrar {
NSString* _pluginKey;
FlutterViewController* _flutterViewController;
}
- (instancetype)initWithPlugin:(NSString*)pluginKey
flutterViewController:(FlutterViewController*)flutterViewController {
self = [super init];
NSAssert(self, @"Super init cannot be nil");
_pluginKey = [pluginKey retain];
_flutterViewController = [flutterViewController retain];
return self;
}
- (void)dealloc {
[_pluginKey release];
[_flutterViewController release];
[super dealloc];
}
- (NSObject<FlutterBinaryMessenger>*)messenger {
return _flutterViewController;
}
- (NSObject<FlutterTextureRegistry>*)textures {
return _flutterViewController;
}
- (void)publish:(NSObject*)value {
_flutterViewController.pluginPublications[_pluginKey] = value;
}
- (void)addMethodCallDelegate:(NSObject<FlutterPlugin>*)delegate
channel:(FlutterMethodChannel*)channel {
[channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
[delegate handleMethodCall:call result:result];
}];
}
- (void)addApplicationDelegate:(NSObject<FlutterPlugin>*)delegate {
id<UIApplicationDelegate> appDelegate = [[UIApplication sharedApplication] delegate];
if ([appDelegate conformsToProtocol:@protocol(FlutterAppLifeCycleProvider)]) {
id<FlutterAppLifeCycleProvider> lifeCycleProvider =
(id<FlutterAppLifeCycleProvider>)appDelegate;
[lifeCycleProvider addApplicationLifeCycleDelegate:delegate];
}
}
- (NSString*)lookupKeyForAsset:(NSString*)asset {
return [_flutterViewController lookupKeyForAsset:asset];
}
- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package {
return [_flutterViewController lookupKeyForAsset:asset fromPackage:package];
}
@end