如何在現有的iOS工程中接入Flutter

如何在現有的iOS工程中接入Flutter(詳見原文

  1. 本文是參考 官方文檔,加上自己的爬坑經驗,總結出的,供大家參考~
  2. 關于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(如下圖)

假設你有一個iOS工程

在該工程路徑下,創建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模塊

二、創建依賴

等待片刻后,終端會輸出圖左內容,工程目錄下會變成圖右樣子:

完成flutter_module的創建

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 BitcodeNO(如下圖)

設置工程所有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
在Xcode工程中添加Dart代碼的build phase

注:務必保證Run ScriptTarget 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 加入項目中

注意: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目錄通過拖拽的方式加入項目中(如下圖),再次運行應該就好了~

將 `~/Work/Projects/flutter_module/.ios/Flutter/flutter_assets`目錄通過拖拽的方式加入項目中

參考文檔

后話

本文原文地址(建議瀏覽,會及時更新):http://www.lxweimin.com/p/af085d4420fd

如果你有好的 idea 或 疑問,請隨時提 issue 或 request。

如果你在開發過程中遇到什么問題,或對iOS開發有著自己獨到的見解,再或是你與我一樣同為菜鳥,都可以關注或私信我的微博。

“Stay hungry. Stay foolish.”

共勉~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容