iOS集成Flutter Module以及flutter_boost使用
一 把Flutter当做成一个组件集成到iOS中
1.1 创建Flutter_Module (name必须为小写)
flutter create -t module name
1.2 引入相关依赖(.yaml)
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'v3.0-preview.9'
1.3 执行安装命令
flutter pub get
1.4 iOS原生工程Podfile修改以及导入
进入iOS原生工程的Podfile文件,写入
flutter_application_path = '../name_flutter' #这里是我们创建的flutter_module的路径
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'iOSProjectName' do
use_frameworks!
install_all_flutter_pods(flutter_application_path)
\# Pods for nativeIOS
end
1.5 执行安装命令
pod install
二 flutter_boost使用(根据官方文档整理)
2.1 Dart部分的准备工作
新建CustomFlutterBinding with混入BoostFlutterBinding
//这里要特别注意,如果你的工程里已经有一个继承自WidgetsFlutterBinding的自定义Binding,则只需要将其with上BoostFlutterBinding
//如果你的工程没有自定义的Binding,则可以参考这个CustomFlutterBinding的做法
//BoostFlutterBinding用于接管Flutter App的生命周期,必须得接入的
class CustomFlutterBinding extends WidgetsFlutterBinding with BoostFlutterBinding {
}
main中初始化
void main() {
//在runApp之前确保BoostFlutterBinding初始化
CustomFlutterBinding();
runApp(MyApp());
}
注册的路由表
static Map<String, FlutterBoostRouteFactory> routerMap = {
'mainPage': (settings, uniqueId) {
return PageRouteBuilder<dynamic>(
settings: settings,
pageBuilder: (_, __, ___) {
Map<String, Object> map = settings.arguments;
String data = map['data'];
return MainPage(
data: data,
);
},
);
},
'simplePage': (settings, uniqueId) {
Map<String, Object> map = settings.arguments;
String data = map['data'];
return PageRouteBuilder<dynamic>(
settings: settings,
pageBuilder: (_, __, ___) {
return SimplePage(data: data);
},
);
}
};
Main.dart完整代码
import 'package:flutter/material.dart';
import 'customFlutterBinding.dart';
import 'simplePage.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'main_page.dart';
void main() {
CustomFlutterBinding();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
static Map<String, FlutterBoostRouteFactory> routerMap = {
'mainPage': (settings, uniqueId) {
return PageRouteBuilder<dynamic>(
settings: settings,
pageBuilder: (_, __, ___) {
Map<String, Object> map = settings.arguments;
String data = map['data'];
return MainPage(
data: data,
);
},
);
},
'simplePage': (settings, uniqueId) {
Map<String, Object> map = settings.arguments;
String data = map['data'];
return PageRouteBuilder<dynamic>(
settings: settings,
pageBuilder: (_, __, ___) {
return SimplePage(data: data);
},
);
}
};
@override
Widget build(BuildContext context) {
return FlutterBoostApp(routeFactory);
}
Route<dynamic> routeFactory(RouteSettings settings, String uniqueId) {
FlutterBoostRouteFactory func = routerMap[settings.name];
if (func == null) {
return null;
}
return func(settings, uniqueId);
}
}
2.2 iOS端准备工作
新建BoostDelegate实现FlutterBoostDelegate完成原生和flutter页面切换操作
#import <Foundation/Foundation.h>
#import <flutter_boost/FlutterBoost.h>
NS_ASSUME_NONNULL_BEGIN
@interface BoostDelegate : NSObject<FlutterBoostDelegate>
@property (nonatomic, strong) UINavigationController *navigationController;
@end
NS_ASSUME_NONNULL_END
#import "BoostDelegate.h"
#import "ViewControllerDemo.h"
#import "ViewController.h"
@implementation BoostDelegate
-(void)pushNativeRoute:(NSString *)pageName arguments:(NSDictionary *)arguments {
BOOL animated = [arguments[@"animated"] boolValue];
BOOL present = [arguments[@"present"] boolValue];
ViewControllerDemo *vc = [[ViewControllerDemo alloc]init];
if (present) {
[self.navigationController presentViewController:vc animated:animated completion:^{
}];
} else {
[self.navigationController pushViewController:vc animated:YES];
}
}
-(void)pushFlutterRoute:(FlutterBoostRouteOptions *)options {
FBFlutterViewContainer *vc = FBFlutterViewContainer.new;
[vc setName:options.pageName uniqueId:options.uniqueId params:options.arguments opaque:options.opaque];
BOOL animated = [options.arguments[@"animated"] boolValue];
BOOL present = [options.arguments[@"present"] boolValue] || !options.opaque;
if (present) {
[self.navigationController presentViewController:vc animated:animated completion:^{
options.completion(YES);
}];
} else {
[self.navigationController pushViewController:vc animated:animated];
options.completion(YES);
}
}
-(void)popRoute:(FlutterBoostRouteOptions *)options {
FBFlutterViewContainer *vc = (id)self.navigationController.presentedViewController;
NSDictionary *map = options.arguments;
NSLog(@"%@", map);
if ([vc isKindOfClass:FBFlutterViewContainer.class] && [vc.uniqueIDString isEqual:options.uniqueId]) {
if (vc.modalPresentationStyle == UIModalPresentationFullScreen) {
[self.navigationController.topViewController beginAppearanceTransition:YES animated:NO];
[vc dismissViewControllerAnimated:YES completion:^{
[self.navigationController.topViewController endAppearanceTransition];
}];
} else {
[vc dismissViewControllerAnimated:YES completion:^{
}];
}
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}
@end
appdelegate中注册
#import <FlutterPluginRegistrant/FlutterPluginRegistrant-umbrella.h>
#import "BoostDelegate.h"
#import <flutter_boost/FlutterBoost.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
BoostDelegate *delegate = [[BoostDelegate alloc]init];
[[FlutterBoost instance] setup:application delegate:delegate callback:^(FlutterEngine *engine) {
}];
.....
}
2.3 具体使用 iOS进入flutter页面 pageName需要和注册的路由名一致
FlutterBoostRouteOptions* options = [[FlutterBoostRouteOptions alloc]init];
options.pageName = @"mainPage";
options.arguments = @{@"animated":@(YES)};
options.completion = ^(BOOL completion) {
};
[[FlutterBoost instance]open:options];
options.onPageFinished = ^(NSDictionary *dic) {
NSLog(@"%@", dic);
};
2.4 flutter进入原生或者返回原生iOS
Model("open native page", () { ///忽略Model是啥
//// 执行push时 如果找不到路由名,那么就会走上面的BoostDelegate push到原生
BoostNavigator.instance.push("homePage", arguments: {
'data': _controller.text
}).then((value) => showTipIfNeeded(value.toString()));
}),
Model("return to native page with data", () {
Map<String, Object> result = {'data': _controller.text};
BoostNavigator.instance.pop(result);
BoostChannel.instance
.sendEventToNative('TTT', {'data': _controller.text});
}),
2.5 iOS和flutter之间的参数传递
flutter部分
////接收消息
///声明一个用来存回调的对象
VoidCallback removeListener;
///添加事件响应者,监听native发往flutter端的事件
removeListener = BoostChannel.instance.addEventListener("yourEventKey", (key, arguments) {
///deal with your event here
return;
});
///然后在退出的时候(比如dispose中)移除监听者
removeListener?.call();
/// 发送消息给native
BoostChannel.instance.sendEventToNative("eventToNative",{"key1":"value1"});
iOS部分
@property (nonatomic, copy) FBVoidCallback removeListener;
_removeListener = [[FlutterBoost instance] addEventListener:^(NSString *name, NSDictionary *arguments) {
self->_label.text = arguments[@"data"];
} forName:@"TTT"];
[[FlutterBoost instance] sendResultToFlutterWithPageName:@"TTTT" arguments:@{
@"aaa": @"1212"
}];