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:
committed by
GitHub
parent
6ef8fbd2a3
commit
bc4d335137
@@ -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",
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "FlutterMacros.h"
|
||||
#include "FlutterNavigationController.h"
|
||||
#include "FlutterPlugin.h"
|
||||
#include "FlutterPluginAppLifeCycleDelegate.h"
|
||||
#include "FlutterTexture.h"
|
||||
#include "FlutterViewController.h"
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user