iOS项目中集成flutter模块找不到自定义插件方法实现

最近一直在研究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 

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet *)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 
#import 

@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 
#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 *)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 installpod update

image.png

本文参考

Flutter Plugin 调用 Native APIs

Add Flutter to existing apps

你可能感兴趣的:(iOS项目中集成flutter模块找不到自定义插件方法实现)