最近一直在研究iOS和flutter项目的混编,发现它的技术难度远高于纯Flutter开发,碰到很多问题都无从下手,网上关于混编的资料还特别少,现在就把在学习中碰到的问题记录一下,和大家一起进步学习。
遇到问题:
写了一个插件,在纯flutter环境下可以正常运行,可是在将flutter项目集成到iOS项目中,用Xcode启动iOS项目,进入flutter界面,却报以下错误:
Unhandled Exception: MissingPluginException(No implementation found for method getPlatformVersion on channel koolearn_test)
代码如下:
AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[ViewController alloc] init];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
ViewController:
#import "ViewController.h"
#import <Flutter/Flutter.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
[self presentViewController:flutterViewController animated:false completion:nil];
}
第一次尝试:引入GeneratedPluginRegistrant
在创建插件工程的时候,flutter插件目录下会自动生成一个example文件,里面是插件的测试工程。打开iOS测试工程,在AppDelegate类中,发现比我写的插件代码多了一行注册代码,果断加入iOS项目。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[ViewController alloc] init];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
[GeneratedPluginRegistrant registerWithRegistry:self];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
尝试结果:失败,仍旧报上面错误
第二次尝试:将RootViewController设置为FlutterViewController
在咸鱼的博客上看到一个解决方法,就是把RootViewController设置为FlutterViewController。测试OK,错误解决。但是我们的工程首页是Native页面,所以Window的rootViewController不能是FlutterViewController。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 显示Window
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:[[FlutterViewController alloc] initWithNibName:nil bundle:nil]];
[self.window setBackgroundColor:[UIColor whiteColor]];
[self.window makeKeyAndVisible];
[GeneratedPluginRegistrant registerWithRegistry:self];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
第三次尝试:引入FlutterEngine
最后在flutter的wiki上发现了一种新的解决办法,新建一个FlutterEngine,让FlutterEngine作为插件的注册对象,问题解决。
AppDelegate:
#import <UIKit/UIKit.h>
#import <Flutter/Flutter.h>
@interface AppDelegate : FlutterAppDelegate
@property (nonatomic,strong) FlutterEngine *flutterEngine;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[ViewController alloc] init];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
self.flutterEngine = [[FlutterEngine alloc] initWithName:@"io.flutter" project:nil];
[self.flutterEngine runWithEntrypoint:nil];
[GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
ViewController:
#import "ViewController.h"
#import <Flutter/Flutter.h>
#import "AppDelegate.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
FlutterEngine *flutterEngine = [(AppDelegate *)[[UIApplication sharedApplication] delegate] flutterEngine];
FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
[self presentViewController:flutterViewController animated:false completion:nil];
}
@end
碰到错误
运行Xcode工程,如果报以下错误,那么对工程进行pod install 或 pod update