前言
前一篇文章講解了Android原生工程如何集成Flutter項目的具體過程悦污,Flutter混合開發(fā)(一):Android項目集成Flutter模塊詳細(xì)指南 ,本篇將帶著大家來一起學(xué)習(xí)原生iOS項目如何集成Flutter切端。
因為每個版本的集成邏輯都是有差別的踏枣,所以這里交代下本篇文章的集成版本:
Flutter (channel dev钙蒙,v1.10.16)
dart (v2.7.0)
Xcode (v11.2)
cocoapds (1.8.4)
創(chuàng)建Flutter module
假如iOS項目的路徑是這樣的:flutter/flutter_hybrid/iOS Project,那么我們需要在iOS Project上一層目錄flutter_hybrid中創(chuàng)建Flutter module躬厌。
cd flutter/flutter_hybrid/
flutter create -t module flutter_module
輸入后控制臺打印如下:
$ flutter create -t module flutter_module
Creating project flutter_module...
flutter_module/test/widget_test.dart (created)
flutter_module/flutter_module.iml (created)
flutter_module/.gitignore (created)
flutter_module/.metadata (created)
flutter_module/pubspec.yaml (created)
flutter_module/README.md (created)
flutter_module/lib/main.dart (created)
flutter_module/flutter_module_android.iml (created)
flutter_module/.idea/libraries/Flutter_for_Android.xml (created)
flutter_module/.idea/libraries/Dart_SDK.xml (created)
flutter_module/.idea/modules.xml (created)
flutter_module/.idea/workspace.xml (created)
Running "flutter pub get" in flutter_module... 1.2s
Wrote 12 files.
All done!
Your module code is in flutter_module/lib/main.dart.
看到All done就表示我們項目創(chuàng)建好了扛施。整個module目錄和原生Flutter基本一樣,主要就是Android匙奴、iOS的宿主工程和lib目錄以及pubspec.yaml文件泼菌。
添加Flutter module依賴
為iOS項目添加依賴需要使用CocoaPods,如果你還沒有用到CocoaPods哗伯,可以參考https://cocoapods.org/上面的說明來安裝CocoaPods篷角。
如果你的項目之前沒有使用過cocoapods,那么需要進(jìn)行初始化生成podfile文件伴澄,進(jìn)入iOS項目的根目錄執(zhí)行:
pod init
然后打開podfile文件非凌,進(jìn)行配置:
# 配置
flutter_application_path = '../flutter_module/'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'iOSFlutterHybrid' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for iOSFlutterHybrid
# 配置
install_all_flutter_pods(flutter_application_path)
target 'iOSFlutterHybridTests' do
inherit! :search_paths
# Pods for testing
end
target 'iOSFlutterHybridUITests' do
# Pods for testing
end
配置添加好后在項目根目錄運(yùn)行以下命令進(jìn)行安裝:
pod install
控制臺輸出:
Analyzing dependencies
Downloading dependencies
Installing Flutter (1.0.0)
Installing FlutterPluginRegistrant (0.0.1)
Installing flutter_module (0.0.1)
Generating Pods project
Integrating client project
[!] Please close any current Xcode sessions and use `iOSFlutterHybrid.xcworkspace` for this project from now on.
Pod installation complete! There are 3 dependencies from the Podfile and 3 total pods installed.
[!] Automatically assigning platform `iOS` with version `13.2` on target `iOSFlutterHybrid` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
這里我們看到有三個依賴安裝完成了敞嗡。并提醒我們關(guān)閉當(dāng)前項目,在根目錄下面使用iOSFlutterHybrid.xcworkspace來打開運(yùn)行項目棱貌。這里可能很多人在執(zhí)行命令的時候會發(fā)現(xiàn)提示0個依賴完成婚脱。這里有可能是你的Xcode版本的問題勺像。因為Flutter要求最低版本是10.2及以上。
當(dāng)在flutter_module/pubspec.yaml中添加一個Flutter插件時篮洁,需要在flutter_module目錄下運(yùn)行:
flutter packages get
來刷新podhelper.rb腳本中的插件列表袁波,然后在iOS目錄下運(yùn)行:
pod install
這樣podhelper.rb腳本才能確保添加的插件和Flutter.framework能夠添加到iOS項目中蜗侈。
目前Flutter還不支持Bitcode,所以集成了Flutter的iOS項目需要禁用Bitcode。
在以下路徑下找到Bitcode并禁用:
Build Settings->Build Options->Enable Bitcode
flutter以前的版本是需要添加build phase以構(gòu)建Dart代碼叫倍,但是最新的版本已經(jīng)不需要添加了吆倦,可以自動構(gòu)建蚕泽。
調(diào)用Flutter module
Flutter為我們提供了兩種調(diào)用方式:FlutterViewController和FlutterEngine桥嗤,F(xiàn)lutterEngine在使用的時候會有一些問題,將在下文進(jìn)行說明荒吏。
FlutterViewController方式:
我們打開ViewController.m文件渊鞋,在里面添加一個加載flutter頁面的方法并且添加一個按鈕看來調(diào)用:
#import "ViewController.h"
#import <Flutter/Flutter.h>
#import "AppDelegate.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(handleButtonAction) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"加載Flutter" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor blueColor]];
button.frame = CGRectMake(100, 100, 160, 60);
[self.view addSubview:button];
}
- (void)handleButtonAction{
FlutterViewController *flutterViewController =[FlutterViewController new];
//設(shè)置路由參數(shù)
[flutterViewController setInitialRoute:@"route2"];
[self presentViewController:flutterViewController animated:false completion:nil];
}
@end
當(dāng)我們運(yùn)行項目點擊加載Flutetr按鈕時,將會調(diào)用Flutter頁面特恬。和Android項目集成一樣,這里的setInitialRoute可以設(shè)置一個json數(shù)組來傳遞需要交互的參數(shù)癌刽。并在Flutter中使用window.defaultRouteName來獲取傳遞的參數(shù)妒穴。
FlutterEngine方式:
我們需要在AppDelegate中對FlutterEngine進(jìn)行初始化。打開AppDelegate.h文件:
#import <UIKit/UIKit.h>
#import <Flutter/Flutter.h>
@interface AppDelegate : FlutterAppDelegate
@property (nonatomic,strong) FlutterEngine *flutterEngine;
@end
在打開AppDelegate.m文件:
// 如果你需要用到Flutter插件時
#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h>
#include "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.flutterEngine = [[FlutterEngine alloc] initWithName:@"io.flutter" project:nil];
[self.flutterEngine runWithEntrypoint:nil];
[GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine]; //如果你需要用到Flutter插件時
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
然后在ViewController.m文件定義的handleButtonAction中調(diào)用:
- (void)handleButtonAction{
FlutterEngine *flutterEngine = [(AppDelegate *)[[UIApplication sharedApplication] delegate] flutterEngine];
FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
[flutterViewController setInitialRoute:@"route2"];
[self presentViewController:flutterViewController animated:false completion:nil];
}
當(dāng)我們運(yùn)行項目點擊加載Flutter按鈕時,將會調(diào)用Flutter頁面呢簸。前文講到使用FlutterEngine會有問題根时,就是我們setInitialRoute傳遞的參數(shù)在flutter中永遠(yuǎn)獲取到的都是 “/” ,這個是Fltter SDK的一個Bug确虱,所以如果必須依賴setInitialRoute替裆,還是使用FlutterViewController的形式來加載Flutter模塊辆童。
熱重啟/重新加載
大家在寫純Flutter應(yīng)用的時候,知道是有熱重啟/重新加載功能的故黑,但是在做混合開發(fā)的過程中庭砍,你會發(fā)現(xiàn)熱重啟/重新加載功能失效了场晶。那么如何在混合開發(fā)中開啟熱重啟/重新加載功能呢?
- 首先接入我們的設(shè)備或者模擬器
- 將我們的App關(guān)閉怠缸,退出后臺峰搪,在terminal中運(yùn)行 flutter attach命令
$ flutter attach
Waiting for a connection from Flutter on Android SDK built for x86...
復(fù)制代碼此時就在等待設(shè)備的連接。這里要注意的是凯旭,如果電腦連接了多臺設(shè)備需要使用 -d 命令來指定一臺設(shè)備概耻,參數(shù)為設(shè)備的id使套。
flutter attach -d '你的設(shè)備id'
然后啟動我們的應(yīng)用會看到控制臺輸出:
Done.
Syncing files to device Android SDK built for x86... 1,393ms
?? To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
An Observatory debugger and profiler on Android SDK built for x86 is available at: http://127.0.0.1:59354/zRsDBfpesrk=/
For a more detailed help message, press "h". To detach, press "d"; to quit, press "q".
這樣就表示我們連接成功了。在輸出的日志中也告訴了我們?nèi)绾问褂脽嶂貑?重新加載功能鞠柄。
在Terminal中輸入以下命令?:?
r : 熱加載侦高;
R : 熱重啟;
h : 獲取幫助厌杜;
d : 斷開連接奉呛;
q : 退出瞧壮;
這里的的 d 和 q 的命令都有退出調(diào)試,區(qū)別在于 d 命令只是單純的斷開而 q 命令會將應(yīng)用退到后臺秦忿。
調(diào)試Dart代碼
同樣在混合開發(fā)過程中我們?nèi)绾握{(diào)試dart代碼呢?
- 關(guān)閉我們的應(yīng)用
- 點擊Android Studio工具欄上的Flutter Attach按鈕(需要安裝Flutter與Dart插件)
- 啟動我們的應(yīng)用
接下來就可以像調(diào)試普通Flutter項目一樣來調(diào)試混合開發(fā)模式下的Dart代碼了。
總結(jié)
本文主要是講解了iOS集成Flutter項目的步驟辜窑,其中也遇到了一些問題切距,由于我的Xcode版本較低话肖,在集成的過程中iOS項目的依賴一直失敗。最后才發(fā)現(xiàn)是Xcode的版本問題床蜘。
如果你覺得文章還不錯扬蕊,請大家點贊分享下,你的肯定是對我最大的鼓勵和支持再愈。