背景
大廠小廠都在搞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ā)工具
- Xcode版本
10.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
- CocoaPods依賴本地Flutter模塊
flutter_application_path = '../my_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
- 每個(gè)target嵌入Flutter
target 'MyApp' do
install_all_flutter_pods(flutter_application_path)
end
- 執(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)題。
解決方案有兩種:
- 執(zhí)行
channel master
或者channel dev
先換個(gè)channel
用函喉。 - 修改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ǔ)充吧~