From c1feee93d31735eb1733894050798e0f49c78002 Mon Sep 17 00:00:00 2001 From: Mikkel Nygaard Ravn Date: Tue, 9 May 2017 12:00:07 +0200 Subject: [PATCH] iOS plugin registry (#9818) --- bin/internal/engine.version | 2 +- packages/flutter_tools/lib/src/plugins.dart | 31 ++++++---------- .../templates/create/ios.tmpl/.gitignore | 4 +- .../Runner.xcodeproj/project.pbxproj.tmpl | 12 +++--- .../create/ios.tmpl/Runner/AppDelegate.m | 37 +++++++++++-------- .../ios.tmpl/Classes/pluginClass.h.tmpl | 3 +- .../ios.tmpl/Classes/pluginClass.m.tmpl | 29 ++++++--------- 7 files changed, 55 insertions(+), 63 deletions(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 8611fad7342..c74beedb03d 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -1b01211ee68fffae3c2acb33ce03b5a3c0d6c774 +cbbf956fcb4338c0a60aef7259416899e7865f6e diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart index 11acbd0369b..b29e7206465 100644 --- a/packages/flutter_tools/lib/src/plugins.dart +++ b/packages/flutter_tools/lib/src/plugins.dart @@ -121,8 +121,8 @@ const String _iosPluginRegistryHeaderTemplate = '''// // Generated file. Do not edit. // -#ifndef PluginRegistry_h -#define PluginRegistry_h +#ifndef GeneratedPluginRegistrant_h +#define GeneratedPluginRegistrant_h #import @@ -130,34 +130,25 @@ const String _iosPluginRegistryHeaderTemplate = '''// #import "{{class}}.h" {{/plugins}} -@interface PluginRegistry : NSObject - -{{#plugins}} -@property (readonly, nonatomic) {{class}} *{{name}}; -{{/plugins}} - -- (instancetype)initWithController:(FlutterViewController *)controller; - +@interface GeneratedPluginRegistrant : NSObject ++ (void)registerWithRegistry:(NSObject*)registry; @end -#endif /* PluginRegistry_h */ +#endif /* GeneratedPluginRegistrant_h */ '''; const String _iosPluginRegistryImplementationTemplate = '''// // Generated file. Do not edit. // -#import "PluginRegistry.h" +#import "GeneratedPluginRegistrant.h" -@implementation PluginRegistry +@implementation GeneratedPluginRegistrant -- (instancetype)initWithController:(FlutterViewController *)controller { - if (self = [super init]) { ++ (void)registerWithRegistry:(NSObject*)registry { {{#plugins}} - _{{name}} = [[{{class}} alloc] initWithController:controller]; + [{{class}} registerWithRegistrar:[registry registrarForPlugin:@"{{class}}"]]; {{/plugins}} - } - return self; } @end @@ -181,9 +172,9 @@ void _writeIOSPluginRegistry(String directory, List plugins) { new mustache.Template(_iosPluginRegistryImplementationTemplate).renderString(context); final Directory registryDirectory = fs.directory(fs.path.join(directory, 'ios', 'Runner')); registryDirectory.createSync(recursive: true); - final File registryHeaderFile = registryDirectory.childFile('PluginRegistry.h'); + final File registryHeaderFile = registryDirectory.childFile('GeneratedPluginRegistrant.h'); registryHeaderFile.writeAsStringSync(pluginRegistryHeader); - final File registryImplementationFile = registryDirectory.childFile('PluginRegistry.m'); + final File registryImplementationFile = registryDirectory.childFile('GeneratedPluginRegistrant.m'); registryImplementationFile.writeAsStringSync(pluginRegistryImplementation); } diff --git a/packages/flutter_tools/templates/create/ios.tmpl/.gitignore b/packages/flutter_tools/templates/create/ios.tmpl/.gitignore index 5ec8cc025e8..38864eed23e 100644 --- a/packages/flutter_tools/templates/create/ios.tmpl/.gitignore +++ b/packages/flutter_tools/templates/create/ios.tmpl/.gitignore @@ -9,8 +9,8 @@ profile DerivedData/ build/ -PluginRegistry.h -PluginRegistry.m +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m *.pbxuser *.mode1v3 diff --git a/packages/flutter_tools/templates/create/ios.tmpl/Runner.xcodeproj/project.pbxproj.tmpl b/packages/flutter_tools/templates/create/ios.tmpl/Runner.xcodeproj/project.pbxproj.tmpl index 731bb1a6476..66679354b1b 100644 --- a/packages/flutter_tools/templates/create/ios.tmpl/Runner.xcodeproj/project.pbxproj.tmpl +++ b/packages/flutter_tools/templates/create/ios.tmpl/Runner.xcodeproj/project.pbxproj.tmpl @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* PluginRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* PluginRegistry.m */; }; + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -39,8 +39,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* PluginRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PluginRegistry.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* PluginRegistry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PluginRegistry.m; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -113,8 +113,8 @@ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C147021CF9000F007C117D /* Info.plist */, 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* PluginRegistry.h */, - 1498D2331E8E89220040F4C2 /* PluginRegistry.m */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, ); path = Runner; sourceTree = ""; @@ -237,7 +237,7 @@ files = ( 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 97C146F31CF9000F007C117D /* main.m in Sources */, - 1498D2341E8E89220040F4C2 /* PluginRegistry.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/packages/flutter_tools/templates/create/ios.tmpl/Runner/AppDelegate.m b/packages/flutter_tools/templates/create/ios.tmpl/Runner/AppDelegate.m index 3b6ab51b9e1..2fa3839f876 100644 --- a/packages/flutter_tools/templates/create/ios.tmpl/Runner/AppDelegate.m +++ b/packages/flutter_tools/templates/create/ios.tmpl/Runner/AppDelegate.m @@ -1,38 +1,45 @@ #include "AppDelegate.h" -#include "PluginRegistry.h" +#include "GeneratedPluginRegistrant.h" -@implementation AppDelegate { - PluginRegistry *plugins; -} +@implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. - FlutterViewController *flutterController = - (FlutterViewController *)self.window.rootViewController; - plugins = [[PluginRegistry alloc] initWithController:flutterController]; - return YES; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + [super applicationWillResignActive:application]; } - (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + [super applicationDidEnterBackground:application]; } - (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + [super applicationWillEnterForeground:application]; } - (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + [super applicationDidBecomeActive:application]; } - (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + [super applicationWillTerminate:application]; } +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + options:(NSDictionary *)options { + // Called when the application is asked to open a resource specified by a URL. + return [super application:application openURL:url options:options]; +} @end diff --git a/packages/flutter_tools/templates/plugin/ios.tmpl/Classes/pluginClass.h.tmpl b/packages/flutter_tools/templates/plugin/ios.tmpl/Classes/pluginClass.h.tmpl index 819c2ef934f..560ffa569c7 100644 --- a/packages/flutter_tools/templates/plugin/ios.tmpl/Classes/pluginClass.h.tmpl +++ b/packages/flutter_tools/templates/plugin/ios.tmpl/Classes/pluginClass.h.tmpl @@ -1,5 +1,4 @@ #import -@interface {{pluginClass}} : NSObject -- initWithController:(FlutterViewController *)controller; +@interface {{pluginClass}} : NSObject @end diff --git a/packages/flutter_tools/templates/plugin/ios.tmpl/Classes/pluginClass.m.tmpl b/packages/flutter_tools/templates/plugin/ios.tmpl/Classes/pluginClass.m.tmpl index 3a1e3909f32..1aa97c644ea 100644 --- a/packages/flutter_tools/templates/plugin/ios.tmpl/Classes/pluginClass.m.tmpl +++ b/packages/flutter_tools/templates/plugin/ios.tmpl/Classes/pluginClass.m.tmpl @@ -1,25 +1,20 @@ #import "{{pluginClass}}.h" -@implementation {{pluginClass}} { +@implementation {{pluginClass}} ++ (void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel* channel = [FlutterMethodChannel + methodChannelWithName:@"{{projectName}}" + binaryMessenger:[registrar messenger]]; + {{pluginClass}}* instance = [[{{pluginClass}} alloc] init]; + [registrar addMethodCallDelegate:instance channel:channel]; } -- (instancetype)initWithController:(FlutterViewController *)controller { - self = [super init]; - if (self) { - FlutterMethodChannel *channel = [FlutterMethodChannel - methodChannelWithName:@"{{projectName}}" - binaryMessenger:controller]; - [channel setMethodCallHandler:^(FlutterMethodCall *call, - FlutterResult result) { - if ([@"getPlatformVersion" isEqualToString:call.method]) { - result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] - systemVersion]]); - } else { - result(FlutterMethodNotImplemented); - } - }]; +- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + if ([@"getPlatformVersion" isEqualToString:call.method]) { + result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); + } else { + result(FlutterMethodNotImplemented); } - return self; } @end