如何在現有的iOS工程中接入Flutter(詳見原文)
- 本文是參考 官方文檔,加上自己的爬坑經驗,總結出的,供大家參考~
- 關于Flutter的環境安裝、IDE配置,請參看Flutter中文網
開發環境
Flutter
- Dart:v2.0.0
- Flutter:Flutter Release Preview 2
engine.version = 38a646e14cc25f5a56a989c6a5787bf74e0ea386 - IDE:Android Studio
iOS
- Objective-C/Swift:Objective-C
- Xcode:Version 9.4.1 (9F2000)
一、創建Flutter模塊
假設你有一個iOS工程,路徑為 ~/Work/Projects/HybridNativeAppWithFlutter
(如下圖)
在該工程路徑下,創建Flutter模塊:
cd ~/Work/Projects
flutter create -t module flutter_module
注1: Flutter模塊的創建路徑 務必 在
xxx.xcodeproj
工程文件的上一級目錄
例:當前工程文件路徑為~/Work/Projects/HybridNativeAppWithFlutter/HybridNativeAppWithFlutter.xcodeproj
,
則Flutter模塊的創建路徑必須是~/Work/Projects/HybridNativeAppWithFlutter
注2: 當前筆者是通過 Android Studio 開發Flutter,無法直接創建iOS的Flutter模塊(如下圖,后續可能會支持),所以建議用官方的方式,通過如上命令來創建
Android Studio 無法直接創建iOS的Flutter模塊
二、創建依賴
等待片刻后,終端會輸出圖左內容,工程目錄下會變成圖右樣子:
1. 在Podfile文件中添加Flutter app
Flutter framework
需要通過CocoaPods來管理依賴,假設當前項目已經使用了CocoaPods,則直接在 iOS 工程的Podfile
文件中加上如下兩句話:
flutter_application_path = '../flutter_module'
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
注1:如果當前項目沒有使用CocoaPods,請先參考CocoaPods官網 或 《CocoaPods安裝方法》進行安裝;
注2:完整的Podfile文件如下:source 'https://github.com/CocoaPods/Specs.git' platform :ios, '9.0' inhibit_all_warnings! target 'HybridNativeAppWithFlutter' do end flutter_application_path = '../flutter_module' eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
然后:
pod install
注: 務必確保工程所有Target的
Enable Bitcode
為NO
(如下圖)
設置工程所有Target的 `Enable Bitcode`為`NO`
2.在Xcode工程中添加Dart代碼的build phase
如下圖,在Xcode工程中,選擇TARGET -> Build Phases -> +號 -> New Run Script Phase
,然后將如下命令粘貼到文本框中,最后通過快捷鍵?B
編譯:
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
注:務必保證
Run Script
在Target Dependencies phase
后面
三、在iOS項目中,通過FlutterViewController
跳轉至Flutter頁面
參考如下代碼,修改你的工程文件:
AppDelegate.h/m
-
AppDelegate.h
#import <UIKit/UIKit.h> #import <Flutter/Flutter.h> @interface AppDelegate : FlutterAppDelegate @end
-
AppDelegate.m
#import "AppDelegate.h" #import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h> // Only if you have Flutter Plugins @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end
ViewController.h/m
-
ViewController.h
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end
-
ViewController.m
#import "ViewController.h" #import <Flutter/Flutter.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor lightGrayColor]; 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 { FlutterViewController *flutterViewController = [[FlutterViewController alloc] init]; flutterViewController.view.backgroundColor = [UIColor cyanColor]; [flutterViewController setInitialRoute:@"route1"]; [self presentViewController:flutterViewController animated:YES completion:nil]; } @end
此時,如果直接運行、點擊按鈕后,會看到控制臺的報錯,并且頁面也沒有任何內容顯示:
其中,重要的兩行提示:
2018-10-23 22:48:48.990075+0800 HybridNativeAppWithFlutter[37728:5932375] Failed to find assets path for "flutter_assets"
2018-10-23 22:48:49.057530+0800 HybridNativeAppWithFlutter[37728:5932574] [VERBOSE-2:engine.cc(114)] Engine run configuration was invalid.
所以,我們要把flutter_assets
和 給加入項目中:Flutter.framework
注意:
flutter_assets
不能使用Create groups
的方式添加,只能使用Creat folder references
的方式添加進Xcode項目內,否則跳轉flutter會頁面渲染失敗(頁面空白)
使用 Creat folder references 的方式添加 flutter_assets 進Xcode項目內
至此,就已經完成了 在現有的iOS工程中接入Flutter 的所有流程~~
運行后的畫面 | 點擊按鈕,跳轉至Flutter頁面 |
---|---|
運行后的畫面
|
點擊按鈕,跳轉至Flutter頁面
|
四、熱啟動/熱加載 與 Dart代碼調試
連接真機或是啟動模擬器,可以通過如下命令連通Flutter&iOS項目,實現 熱啟動/熱加載:
cd ~/Work/Projects/flutter_module
flutter attach
此時輸入r
可熱加載,q
退出,執行效果如下圖:
五、下載代碼
該示例工程下載地址:https://github.com/AndyM129/HybridNativeAppWithFlutter
【友情提示】
在拉取代碼后,若直接運行iOS工程,可能會報錯誤
在拉取代碼后,若直接運行iOS工程,可能會報如上錯誤。
原因:
~/Work/HybridNativeAppWithFlutterDemo/flutter_module/.ios/Flutter/Generated.xcconfig
路徑下的相關配置中 路徑錯了(如下圖)
相關配置中 路徑錯了解決方法是:先運行下 Flutter項目,然后就可以了
六、常見問題
1. 修改了Dart代碼,但iOS工程運行時未正確的同步、顯示
通常,flutter模塊代碼做了稍大的修改(如增刪的文件)后,flutter與iOS主工程的同步死后就有問題了,后者無法正確顯示這些修改。
解決該問題,可以再次將 ~/Work/Projects/flutter_module/.ios/Flutter/flutter_assets
目錄通過拖拽的方式加入項目中(如下圖),再次運行應該就好了~
參考文檔
- 官網 Add Flutter to existing apps:https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps
- iOS Native混編Flutter交互實踐:http://www.lxweimin.com/p/5f4aaa72d509
后話
本文原文地址(建議瀏覽,會及時更新):http://www.lxweimin.com/p/af085d4420fd
如果你有好的 idea 或 疑問,請隨時提 issue 或 request。
如果你在開發過程中遇到什么問題,或對iOS開發有著自己獨到的見解,再或是你與我一樣同為菜鳥,都可以關注或私信我的微博。
- 微信:Andy_129
- 微博:@Developer_Andy
- 簡書:Andy__M
“Stay hungry. Stay foolish.”
共勉~