Flutter 與 iOS 混合項(xiàng)目初探

背景

大廠小廠都在搞Flutter,就問(wèn)你慌不慌击喂!

國(guó)內(nèi)一些混合集成方案的文章大部分都太老了维苔,參考價(jià)值不高,并且很容易讓初學(xué)者頭大懂昂。

前言

本文非闡述Flutter相關(guān)的原理介时,優(yōu)勢(shì),發(fā)展現(xiàn)狀等問(wèn)題,只介紹在與現(xiàn)有的iOS項(xiàng)目做混合開發(fā)的實(shí)踐沸柔,以及混合過(guò)程中的一些坑循衰。目前混合開發(fā)已有2個(gè)頁(yè)面開發(fā)完成,等待用戶檢驗(yàn)褐澎。

開發(fā)工具

  1. Xcode版本 10.2
  2. Visual Studio Code 1.41.0

環(huán)境依賴

Flutter開發(fā)環(huán)境配置過(guò)程就不細(xì)說(shuō)了会钝,官網(wǎng)文檔已經(jīng)寫的很詳細(xì)了。

目前使用Flutter SDK版本為 v1.9.1+hotfix.6

環(huán)境配置完成后執(zhí)行 flutter doctor 做下檢查

Doctor summary (to see all details, run flutter doctor -v):
[?] Flutter (Channel unknown, v1.9.1+hotfix.6, on Mac OS X 10.14.4 18E226,
    locale zh-Hans-CN)
 
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor
      --android-licenses
[!] Xcode - develop for iOS and macOS (Xcode 10.2)
    ! CocoaPods out of date (1.6.0 is recommended).
        CocoaPods is used to retrieve the iOS and macOS platform sides plugin
        code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To upgrade:
        sudo gem install cocoapods
[?] Android Studio (version 3.5)
[?] VS Code (version 1.41.0)
[?] Connected device (1 available)

! Doctor found issues in 2 categories.

可以看到要求CocoaPods版本為1.6.0及以上工三,目前我們?cè)谑褂?code>1.5.3版本迁酸,不過(guò)這只是個(gè)警告,影響不大俭正,后續(xù)升級(jí)CocoaPods自然會(huì)解決這個(gè)問(wèn)題奸鬓。

混合方案

混合方案這一塊官方也是經(jīng)歷了好幾個(gè)版本的變更,最初混合的方案比較麻煩掸读,官方文檔寫的也不是很詳細(xì)串远,不過(guò)在Flutter1.12 發(fā)布后,混合方案文檔做了更新儿惫,2種混合方案寫的也很簡(jiǎn)單易懂澡罚。 這里我們也是采用了官方推薦的方案(使用CocoaPods依賴管理)。

  • 創(chuàng)建Flutter模塊(Flutter相關(guān)頁(yè)面的代碼都在這里)姥闪。
cd some/path/
flutter create --template module my_flutter

這里推薦將Flutter模塊跟iOS工程模塊放在同級(jí)目錄下

some/path/
├── my_flutter/
└── MyApp/
  • 修改Podfile
  1. CocoaPods依賴本地Flutter模塊
flutter_application_path = '../my_flutter'
 load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
  1. 每個(gè)target嵌入Flutter
target 'MyApp' do
   install_all_flutter_pods(flutter_application_path)
 end
  1. 執(zhí)行pod install這里是通過(guò)podhelper.rb腳本將Flutter工程里面.ios目錄下相關(guān)的產(chǎn)物嵌入到iOS工程。
  • Flutter.framework(Flutter engine bundle)
  • App.framework(Dart code)
  • Flutter plugins

相關(guān)產(chǎn)物的生成記得在Flutter模塊下執(zhí)行flutter build ios操作砌烁。

按照上面3步操作完成后我們可以看到Flutter產(chǎn)物已經(jīng)集成到iOS工程了

Analyzing dependencies
Fetching podspec for `Flutter` from `../../finance-flutter-module/.ios/Flutter/engine`
Fetching podspec for `FlutterPluginRegistrant` from `../../finance-flutter-module/.ios/Flutter/FlutterPluginRegistrant`
Fetching podspec for `connectivity` from `../../finance-flutter-module/.ios/Flutter/.symlinks/connectivity/ios`
Fetching podspec for `flutter_boost` from `../../finance-flutter-module/.ios/Flutter/.symlinks/flutter_boost/ios`
Fetching podspec for `rrd_flutter` from `../../finance-flutter-module/.ios/Flutter`
Fetching podspec for `url_launcher` from `../../finance-flutter-module/.ios/Flutter/.symlinks/url_launcher/ios`
Downloading dependencies
Installing Flutter (1.0.0)
Installing FlutterPluginRegistrant (0.0.1)
Installing Reachability (3.2)
Installing connectivity (0.0.1)
Installing flutter_boost (0.0.2)
Installing rrd_flutter (0.0.1)
Installing url_launcher (0.0.1)
Generating Pods project
Integrating client project

解決報(bào)錯(cuò)

完成混合后run工程出現(xiàn)如下error

/Build/Products/Debug-iphonesimulator/investment.app/Frameworks/Flutter.framework: Permission denied

這里應(yīng)該是Flutter1.9的簽名沖突Bug筐喳,官方在1.10.2已經(jīng)修復(fù)這個(gè)問(wèn)題。

解決方案有兩種:

  1. 執(zhí)行 channel master 或者 channel dev 先換個(gè)channel用函喉。
  2. 修改Flutter SDK文件厅瞎,打開flutter/packages/flutter_tools/bin/xcode_backend.sh文件溯壶,將
RunCommand find "${derived_dir}/engine/Flutter.framework" -type f -exec chmod a-w "{}" \;

替換為

RunCommand find "${derived_dir}/engine/Flutter.framework" -type f -iname '.h' -exec chmod a-w "{}" \;

我們采用了第二種方案,修改后再次run發(fā)現(xiàn)工程已經(jīng)可以運(yùn)行了,到這里Flutter和iOS的初步混合已經(jīng)完成了扁耐。

調(diào)試和Hot Reload

flutter attach之后使用終端或者VSCode做Flutter頁(yè)面調(diào)試非常方便,這里還是推薦使用VSCode弧哎,畢竟在代碼和終端之間來(lái)回切換不停的按r很煩朵逝。

bogon:my_flutter yin$ flutter attach
Checking for advertised Dart observatories...
Waiting for a connection from Flutter on iPhone X...
Done.
Syncing files to device iPhone X...                              1,328ms

??  To hot reload changes while running, press "r". To hot restart (and rebuild
state), press "R".
An Observatory debugger and profiler on iPhone X is available at:
http://127.0.0.1:63823/uO5BqqTmOrE=/
For a more detailed help message, press "h". To detach, press "d"; to quit,
press "q".

不過(guò)Android Studio對(duì)Flutter開發(fā)調(diào)試支持的要更好,畢竟是同廠出品坷襟,會(huì)有一些新的調(diào)試功能和特性可以使用奸柬,感興趣的同學(xué)可以研究下。作為一個(gè)用慣了Xcode的人婴程,目前來(lái)說(shuō)VSCode已經(jīng)可以滿足我的開發(fā)需求了廓奕,就不去折騰Android Studio,畢竟開發(fā)React Native也還是要用VSCode,搞太多IDE怕自己凌亂~

這里有一點(diǎn)需要注意下就是 flutter attach 之后可能會(huì)一直為等待狀態(tài)

Checking for advertised Dart observatories...
Waiting for a connection from Flutter on iPhone X...

這時(shí)我們殺掉APP進(jìn)程重新啟動(dòng)就可以連接了桌粉。這里猜測(cè)是每次Native工程做Flutter相關(guān)初始化時(shí)候才會(huì)做一次attach蒸绩。

總結(jié)

我們目前使用的方案是Flutter官方推薦的混合方案,優(yōu)點(diǎn)缺點(diǎn)并存:

  • 優(yōu)點(diǎn):混合集成簡(jiǎn)單铃肯,混合過(guò)程很多事情Flutter官方已經(jīng)幫我們做好了
  • 缺點(diǎn):雖然iOS工程倉(cāng)庫(kù)和Flutter Module工程倉(cāng)庫(kù)是分離的患亿,但緊緊做到了代碼分離,實(shí)際運(yùn)行兩個(gè)工程是相互依賴的缘薛,也就是iOS和Android端的開發(fā)者本地都要安裝一套Flutter環(huán)境窍育。

目前這套混合方案還比較適合我們(iOS和Android都為3人)這種較小的團(tuán)隊(duì),如果團(tuán)隊(duì)人員比較多或者還有Flutter單獨(dú)的項(xiàng)目組的話宴胧,這種混合方案可能就比較笨重了漱抓,當(dāng)然網(wǎng)上還有一些Flutter混合開發(fā)工程化的方案,這里我們暫時(shí)不做討論恕齐,后續(xù)如果去研究了在做補(bǔ)充吧~

相關(guān)鏈接

Flutter環(huán)境配置

官方混合文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乞娄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子显歧,更是在濱河造成了極大的恐慌仪或,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件士骤,死亡現(xiàn)場(chǎng)離奇詭異范删,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)拷肌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門到旦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人巨缘,你說(shuō)我怎么就攤上這事添忘。” “怎么了若锁?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵搁骑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我又固,道長(zhǎng)仲器,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任仰冠,我火速辦了婚禮娄周,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沪停。我一直安慰自己煤辨,他們只是感情好裳涛,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著众辨,像睡著了一般端三。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鹃彻,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天郊闯,我揣著相機(jī)與錄音,去河邊找鬼蛛株。 笑死团赁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谨履。 我是一名探鬼主播欢摄,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼笋粟!你這毒婦竟也來(lái)了怀挠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤害捕,失蹤者是張志新(化名)和其女友劉穎绿淋,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尝盼,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吞滞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盾沫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片裁赠。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖疮跑,靈堂內(nèi)的尸體忽然破棺而出组贺,到底是詐尸還是另有隱情凸舵,我是刑警寧澤祖娘,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站啊奄,受9級(jí)特大地震影響渐苏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菇夸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一琼富、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庄新,春花似錦鞠眉、人聲如沸薯鼠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)出皇。三九已至,卻和暖如春哗戈,著一層夾襖步出監(jiān)牢的瞬間郊艘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工唯咬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纱注,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓胆胰,卻偏偏與公主長(zhǎng)得像狞贱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子煮剧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容