本文将简单梳理一下 iOS 工程接入的 Flutter Boost 的流程,以作为前文的补充。
参见前文:Flutter Boost 混合开发实践与源码解析(以 Android 为例),Flutter Module 也依旧用前文生成的,目录结构依旧如前文所述,不再赘述。
- 接入
2.1 工程准备
准备一个配有 Cocoapods 的空白工程,在 Podfile 中配置我们之前准备好的 Flutter Module 作为依赖:
flutter_application_path = '../flutter_module'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'FlutterHybridiOS' do
install_all_flutter_pods(flutter_application_path)
end
接着在工程根目录下运行 pod install ,即可集成上 Flutter Module。看到我们的 Pods 中多了以下几个模块,即说明集成成功。
接着在工程根目录下运行 pod install
,即可集成上 Flutter Module。看到我们的 Pods 中多了以下几个模块,即说明集成成功。
如不了解 Cocoapods,请参见 CocoaPods 使用指南
2.2 实现路由类
这一块直接参照 Flutter Boost 官方提供的 example 就好了:
PlatformRouterImp.h:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <flutter_boost/FlutterBoost.h>
NS_ASSUME_NONNULL_BEGIN
@protocol FLBPlatform;
/**
* 实现平台侧的页面打开和关闭,不建议直接使用用于页面打开,建议使用FlutterBoostPlugin中的open和close方法来打开或关闭页面;
* FlutterBoostPlugin带有页面返回数据的能力
*/
@interface PlatformRouterImp : NSObject<FLBPlatform>
@property (nonatomic,strong) UINavigationController *navigationController;
@end
NS_ASSUME_NONNULL_END
PlatformRouterImp.m:
#import "PlatformRouterImp.h"
#import <flutter_boost/FlutterBoost.h>
@interface PlatformRouterImp()
@end
@implementation PlatformRouterImp
#pragma mark - Boost 1.5
- (void)open:(NSString *)name
urlParams:(NSDictionary *)params
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
if(completion) completion(YES);
}
- (void)present:(NSString *)name
urlParams:(NSDictionary *)params
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{
if(completion) completion(YES);
}];
}
- (void)close:(NSString *)uid
result:(NSDictionary *)result
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
animated = YES;
FLBFlutterViewContainer *vc = (id)self.navigationController.presentedViewController;
if([vc isKindOfClass:FLBFlutterViewContainer.class] && [vc.uniqueIDString isEqual: uid]){
[vc dismissViewControllerAnimated:animated completion:^{}];
}else{
[self.navigationController popViewControllerAnimated:animated];
}
}
@end
可以看到,Flutter Boost 支持常规 push,也支持打开模态弹窗,也支持手动 pop。
2.3 绑定路由管理
AppDelegate.h:
#import <UIKit/UIKit.h>
#import <flutter_boost/FlutterBoost.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nullable, nonatomic, strong) UIWindow *window;
@end
AppDelegate.m:
#import "AppDelegate.h"
#import "PlatformRouterImp.h"
#import <flutter_boost/FlutterBoost.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
PlatformRouterImp *router = [PlatformRouterImp new];
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterEngine *engine) {
}];
UITabBarController *tabVC = [[UITabBarController alloc] init];
UINavigationController *rvc = [[UINavigationController alloc] initWithRootViewController:tabVC];
router.navigationController = rvc;
return YES;
}
3. 使用
- (void)openClick:(UIButton *)button
{
[FlutterBoostPlugin open:@"first" urlParams:@{kPageCallBackId:@"MycallbackId#1"} exts:@{@"animated":@(YES)} onPageFinished:^(NSDictionary *result) {
NSLog(@"call me when page finished, and your result is:%@", result);
} completion:^(BOOL f) {
NSLog(@"page is opened");
}];
}
- (void)openPresentClick:(UIButton *)button
{
[FlutterBoostPlugin open:@"second" urlParams:@{@"present":@(YES),kPageCallBackId:@"MycallbackId#2"} exts:@{@"animated":@(YES)} onPageFinished:^(NSDictionary *result) {
NSLog(@"call me when page finished, and your result is:%@", result);
} completion:^(BOOL f) {
NSLog(@"page is presented");
}];
}
同样的,这里可在 Native 端用两种不同的方式去打开我们在 Flutter Module 中注册好的路由名。
至此,我们成功在 iOS 工程中接入了 Flutter Boost,那就开启我们的混编之旅吧~