Flutter iOS原生集成流程
我這兒用的Flutter版本是1.7.8+hotfix.4,在與最新版本在SDK中有些許區(qū)別
一铲觉、Flutter 提供的 Native Flutter 混合工程方式
1. 創(chuàng)建 Flutter 工程
請(qǐng)自行 百度/Google Flutter 安裝教程,安裝Flutter美莫。然后到任意目錄下執(zhí)行flutter create -t module my_flutter菜拓,"my_flutter" 是要?jiǎng)?chuàng)建的 Flutter 工程的名稱(chēng)。
2. 通過(guò) Cocoapods 將 Flutter 引入 現(xiàn)有 Native 工程
在Podfile添加以下下代碼
flutter_application_path = "xxx/xxx/my_flutter"
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
執(zhí)行pod install
3. 修改 Native 工程
打開(kāi)Xcode工程系宫,選擇要加入 Flutter App 的 target索昂,選擇 Build Phases,點(diǎn)擊頂部的 + 號(hào)扩借,選擇 New Run Script Phase椒惨,然后輸入以下腳本
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed
4. 編譯通過(guò),開(kāi)始編寫(xiě)FlutterViewController代碼
FlutterViewController.h
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface XKFluttersViewController : FlutterViewController
@end
NS_ASSUME_NONNULL_END
FlutterViewController.m
#import "XKFluttersViewController.h"
#import "XKFlutterHandler.h"
@interface XKFluttersViewController ()<FlutterPluginRegistry>
@property (strong, nonatomic) FlutterMethodChannel* batteryChannel;
@property (assign, nonatomic) BOOL isFirst;
@end
@implementation XKFluttersViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_isFirst = YES;
[self initFlutter];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[UIView animateWithDuration:.25f animations:^{
self.view.frame = CGRectMake(0, [SYHandler statusBarHeight] , SCREEN_WIDETH, SCREEN_HEIGHT - [SYHandler statusBarHeight]);
}];
if (_isFirst) {
_isFirst = NO;
// 與flutter通信潮罪,通知flutter頁(yè)面已經(jīng)顯示
[_batteryChannel invokeMethod:@"onResume" arguments:nil];
}
}
- (void)initFlutter {
NSString* methodName = @"xiaoka";
_batteryChannel = [FlutterMethodChannel methodChannelWithName:methodName
binaryMessenger:self];
WS(weakSelf);
[_batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
// TODO
SS(strongSelf, weakSelf)
[XKFlutterHandler handleCallWithMethod:call.method
arguments:call.arguments
controller:strongSelf
handler:result];
}];
}
- (void)dealloc {
self.batteryChannel = nil;
NSLog(@"釋放 FlutterViewController");
}
@end
XKFlutterHandler.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface XKFlutterHandler : NSObject
/**
* 處理回調(diào)方法和參數(shù)
@param method 方法
@param arguments 參數(shù)
@param controller 控制器
@param handler block
*/
+ (void)handleCallWithMethod:(NSString *)method
arguments:(id)arguments
controller:(UIViewController *)controller
handler:(FlutterResult)handler;
@end
XKFlutterHandler.m
#import "XKFlutterHandler.h"
@implementation XKFlutterHandler
+ (void)handleCallWithMethod:(NSString *)method
arguments:(id)arguments
controller:(UIViewController *)controller
handler:(FlutterResult)handler
{
// 與flutter約定的方法名
if ([method isEqualToString:@"getAppKey"]) {
// 獲取appkey
NSString* appkey = @"appkey";
// 返回?cái)?shù)據(jù)給Flutter
handler(appkey);
}
}
至此就可以快樂(lè)的使用flutter的各種頁(yè)面了
5.熱重載
在run Xcode項(xiàng)目時(shí)康谆,現(xiàn)在vs或as中把flutter的debug指定端口上领斥,然后在Xcode項(xiàng)目啟動(dòng)時(shí)Flutter.framework就可以連接并及時(shí)刷新頁(yè)面
flutter attach --debug-port=端口號(hào)
二、在開(kāi)發(fā)過(guò)程中的注意事項(xiàng)??
1. setInitialRouter路由失效
因?yàn)樵谖业男枨罄锩媸牵?在iOS現(xiàn)有工程集成flutter項(xiàng)目沃暗,然后可以跳轉(zhuǎn)到任意的flutter業(yè)務(wù)頁(yè)面月洛。
// 使用全局引擎初始化
FlutterViewController* flutterViewController = [[FlutterViewController alloc] initWithEngine:appdelegate.engine nibName:nil bundle:nil];
// (無(wú)效)
[flutterViewController setInitialRouter:@"test"];
// (會(huì)有push的效果)
[flutterViewController pushRoute:@"test"];
// 使用默認(rèn)初始化 (有效)
FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
[flutterViewController setInitialRouter:@"test"];