首先区分两个概念'flutter-boot' 和'flutter_boost'都是alibba开源的flutter工具,可是是两个彻底不一样的东西。node
新一代Flutter-Native混合解决方案。 FlutterBoost是一个Flutter插件,它能够轻松地为现有原生应用程序提供Flutter混合集成方案。FlutterBoost的理念是将Flutter像Webview那样来使用。在现有应用程序中同时管理Native页面和Flutter页面并不是易事。 FlutterBoost帮你处理页面的映射和跳转,你只需关心页面的名字和参数便可(一般能够是URL)。android
这是一个帮助你在已有原生应用的状况下,搭建flutter混合开发环境的工具。 咱们提供了标准的混合工程结构,同时支持混合栈(一套原生和flutter以前页面通讯和过渡的方案)的快速接入。ios
以上是摘抄GitHub上flutter-boot 和 flutter_boost的官方介绍,也由于官方文档上的集成步骤太过简略,在集成的过程当中才过了很多的坑,因此都记录下来而且分享出来,但愿能够给看文章的你,带去一些解决方案和思路。git
本文主要记录一次flutter-boot的集成过程,对于flutter_boost的使用放在后续的文章中再介绍。github
已有一个维护迭代过多个版本的Native工程,而且已经作过组件化,拆分了多个组件(就是常见的组合组件的方法,经过CocoaPods的方式添加安装各个组件,制做CocoaPods远程私有库,将其发不到公司的gitlab或GitHub,使工程可以Pod下载下来),本次集成flutter-boot的目的是要把其中一个组件,使用flutter重写。shell
这里强调作过组件化,是由于不少问题都是由于组件化了才引发的若是只是一个单纯的工程集成的话,会简单很多,并且后续若是只是某个组件须要依赖flutter,还须要有一些特殊的操做。npm
这里能够跟着我一块儿来操做,下面的步骤我都写得尽可能详细,遇到的问题都有截图或者文字描述,以及解决方案跟在后面。ruby
这里能够是你的Native路径 , 也能够是一个新建立的文件夹,这里我是用了一个新的文件夹路径,目的是保证以后的路径和官方文档上的目录结构一致。bash
somepath/my_repo
└──my_android
└──my_ios
└──my_flutter
└──.git
└──.gitignore
└──android_shell
└──ios_shell
└──android
└──ios
复制代码
问题一:link 失败,这里忘记截图了。。。特别抱歉app
解决方案:
拥有^1.5.0的flutter环境
复制代码
问题二:podfile内容copy出错,你也可能不会遇到这个问题,这里是flutter-boot自己的bug,只去匹配了字符串'end',恰好咱们使用了这个日历的库,就到这里把podfile文件中的内容给截断了
pod 'FSCalendar', '2.8.0' # 日历
复制代码
解决方案:
post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
target.build_configurations.each do |config|
...
end
end
end
复制代码
问题三:
这里是你工程的post_install和init命令生成的fbpodhelper.rb中的post_install冲突致使,
解决方案:
flutter_application_path = fbFlutterPath
require File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
复制代码
改成:
# ============= Flutter config begin ============== #
flutter_application_path = './fpf_flutter/'
podhelper_path = File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
podhelper_content = File.read(podhelper_path);
podhelper_post_isntall = "post_install do |installer|";
# 当post_install重复时须要去重以免发生pod install错误:multiple post_install hooks is unsupported
if podhelper_content.scan(/(#{podhelper_post_isntall})/).length > 0 then
podhelper_buffer = podhelper_content.gsub(podhelper_post_isntall, "def update_configs(installer, framework_dir)")
eval(podhelper_buffer, binding)
else
eval(File.read(podhelper_path), binding)
end
# ============= Flutter config end ============== #
复制代码
info [init] 你能够在建立Android工程后调用 flutter-boot link来关联flutter
info [init] 混合工程初始化完成
复制代码
你觉得到这里就真的完成了吗,run一下~~ 记得要选择 Runner target,好像确实能够成功。可是flutter-boot的做用是你能够有两个开发视角,flutter视角下,不须要关心native,native视角,甚至能够不用安装flutter环境。那么,去flutter视角看一下,把flutter module拖入VSCode打开,而后fn+f5,运行起来
那么在flutter视角运行起来了吗
问题四: Run Flutter Build Script 中的脚本./my_flutter_module/.ios/Flutter/flutter_export_environment.sh 路径找不到,一个很奇怪的现象,pod install成功后查看路径,没问题,可是flutter run以后,这里的路径就改变了,相对路径错误,确实找不到这个脚本
解决方案:
flutter_export_environment_path = File.join(project_directory_pathname, relative, 'flutter_export_environment.sh');
复制代码
In AppDelegate.h:
@import UIKit;
@import Flutter;
@interface AppDelegate : FlutterAppDelegate
@property (nonatomic,strong) FlutterEngine *flutterEngine;
@end
复制代码
In AppDelegate.m:
@import FlutterPluginRegistrant; // Only if you have Flutter Plugins
#import "AppDelegate.h"
@implementation AppDelegate
// This override can be omitted if you do not have any Flutter Plugins.
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.flutterEngine = [[FlutterEngine alloc] initWithName:@"io.flutter" project:nil];
[self.flutterEngine runWithEntrypoint:nil];
[GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
复制代码
In ViewController.m
#import "AppDelegate.h"
#import "ViewController.h"
@import Flutter;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:@selector(handleButtonAction)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"Press me" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor blueColor]];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[self.view addSubview:button];
}
- (void)handleButtonAction {
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
复制代码
至此,flutter-boot 环境集成成功!!! 喜大普奔啊,终于不报错了~~
可是,回到咱们最初集成flutter-boot的目的,是要使用flutter重写某一个业务线。由于是组件化的工程,因此flutter引擎的注册也不但愿暴露在APPdelegate中,而是放在一个管理各个业务线分发的平台组件中,那么就涉及到,某一个组件中要使用flutter。
用呗,主工程都能用,组件同样能用,而后,当你在组件代码中添加以下代码以后:
#import <Flutter/Flutter.h>
#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h>
复制代码
找不着,各类找不着啊。。。好像各个业务线组件根本就不能引用flutter以及flutter_module
到这里集成flutter-boot 才算取得了阶段性的胜利✌️,但愿这篇文章,能够给广大敢于尝试flutter-boot的开发人员,带去一些福利(主要是节省一些时间,都不是什么难解决的问题,就是得不断的尝试)。
在这个过程当中,也去看了GitHub上他们全部开放和关闭的issues,而且尝试了N次,过程比较坎坷,不过成功了仍是很可的事😃。
2019.12.11 补充 flutter-boot 推到远端以后,其余同事拉代码,装flutter-boot以后遇到的一些问题记录:
问题一:
产生缘由: 曾用 root 用户进行了局部安装npm包,留下所属权为 root 的文件,致使普通用户 没法访问 root的文件内容。
解决方案:
问题二:my_flutter_module中数据缺失
就是别的同事拉下flutter_module中的代码里面,没有engine这个文件夹
解决方案:
问题三: native视角如何使用
其实这个也不能算是个问题啦,应该归到上面的使用步骤里面,毕竟这个flutter-boot的环境搭建起来,是要给你们一块儿用的,又不是指给本身用😀
其实切换到native视角,就会以为这个工具,和我最开始选择用flutter-boot的初衷有一些偏离。最初,咱们是但愿有一套彻底不影响原生开发的框架,去接入flutter,彻底不影响是什么意思呢,领导但愿,native开发,不须要安装flutter环境,不须要,不须要,不须要,重要的地方强调一下,可是经过这几天对flutter-boot的研究,发现根本作不到这一点。
首先别人拉下native代码和flutter代码以后,须要执行link命令去作软链接,可是自己flutter-boot就是依赖flutter库的,可能说依赖不太准确,可是link命令中就有判断flutter版本的逻辑,若是没有flutter的开发环境,这一步就过不去,那你的native和flutter如何连接上呢??
解决方案:
若是看这篇文章的小伙伴,有更好的方式,欢迎交流!!!