Flutter - 將 Flutter 集成到現有項目(iOS - Framework篇)

本篇文章大幅參考了 caijinglong 大佬的總結文章: 把flutter做爲framework添加到已存在的iOS中android

用 Flutter 來開發,歷來都不多是新開的一個純 Flutter 項目,很大一部分都是 老項目接入 Flutter 來混編。ios

Flutter 官網 - Adding to an iOS app 這裏,官方也給出了一些將 Flutter 集成進入現有 iOS 項目的方法。可是,這些都多多少少的不符合咱們的需求。git

1. 從 Flutter Module 提及

想要把 Flutter 集成進現有 iOS 項目,咱們就必須使用 Flutter Moduleobjective-c

那就先用命令建立一個 Flutter Module:flutter create --template module flutter_test_moduleshell

Flutter APP 和 Flutter Module 的不一樣之處在於 pubspec.yaml 最後一段:ruby

# This section identifies your Flutter project as a module meant for
# embedding in a native host app. These identifiers should _not_ ordinarily
# be changed after generation - they are used to ensure that the tooling can
# maintain consistency when adding or modifying assets and plugins.
# They also do not have any bearing on your native host application's
# identifiers, which may be completely independent or the same as these.
module:
androidX: true
androidPackage: com.example.flutter_test_module
iosBundleIdentifier: com.example.flutterTestModule
複製代碼

這一段代碼,把該 Flutter 項目標註爲一個 module,用於嵌入到原生 app 裏。bash

這裏面設置了是否使用 androidx,Android 和 iOS 的 APP id。app

2. iOS原生項目所需的文件

先說一下,iOS 原生項目引入 Flutter Module 須要以下 Framework:iphone

  1. Flutter.framework
  2. App.framework
  3. FlutterPluginRegistrant.framework (若是有用到原生的插件 - 非純 dart 編寫)
  4. Pods_Runner.framework(若是有用到原生的插件 - 非純 dart 編寫)
  5. *.framework(插件的 framework)

下面繼續集成。ide

Flutter Module 建立完成後,先來給 iOS 打個包,命令以下:flutter build ios --release --no-codesign

而後看一下打包出來的東西,路徑爲 build->ios->Release-iphoneos

若是有第三方庫的話,這裏面應該是有上面說的 三、四、5 的 framework,可是咱們剛建立項目,什麼都沒有加,因此是沒有任何 framework的。

而後去 .ios/Flutter 裏找 一、2:

可是咱們寫程序不可能什麼插件都不用,因此加上一個shared_preferences,再來打包看一下 build 文件夾:

能夠看到確實出現了咱們上面說的 三、四、5 framework,這樣咱們所需的 framework 所有集齊。

3. 使用 cocoapods + git 來管理

由於 caijinglong 大佬 文章內說:

由於找遍了 podfile 的相關文檔, 沒有找到能夠直接引用 framework 的方式

因此須要一個 pod 庫做爲"中轉」

因此咱們就要 跟着作!

使用命令 pod lib create flutter-lib 來建立一個名爲 flutter-lib的私有庫。

建立完成以後,打開 flutter-lib.podspec ,在 end 前面加入一行:

接着咱們在該文件夾內建立一個名爲 ios_frameworks 的文件夾,把咱們剛纔的那麼多 framework 全都粘貼過來。

這個時候咱們的iOS原生項目就能夠引入本地這個庫了:

platform :ios, '8.0'
use_frameworks!

target 'xxx.xxx.xxx' do
   pod 'flutter-lib', :path => 'somepath/flutter-lib'
end
複製代碼

固然,咱們不可能都用本地路徑來引入,因此咱們把這整個 flutter-lib文件夾傳到 git 上,而後這樣引用:

platform :ios, '8.0'
use_frameworks!

target 'xxx.xxx.xxx' do
   pod 'flutter-lib', :git => 'http://xxxx.git'
end
複製代碼

這樣咱們就能夠從 git 上來遠程引用該私有庫了。

若是運行有錯誤的話,能夠去 caijinglong 大佬的博客查看解決辦法。

4. 編寫腳本自動處理

上面都是手動來處理的,包括打包->移動文件->上傳git等。

下面就寫一個腳原本處理一下(基於 caijinglong 大佬):

ios_project_name='xxx'	# 項目名稱
ios_out_path='xxx/ios_frameworks'	# 文件輸出路徑
flutter_git_path='http://xxx/xxx/xxx.git'	# git 項目路徑

function customEcho(){
  echo "\033[1;32m$1\033[0m"
}
customEcho '\n1. 執行 flutter clean'
flutter clean || exit -1

customEcho '\n2. 清空build文件夾'
rm -rf $ios_project_name
rm -rf build
echo '清空完成'

customEcho '\n3. 生成 iOS frameworks'
flutter build ios --release --no-codesign || exit -1 

customEcho "\n4. 從 git 上克隆 frameworks 項目"
git clone $flutter_git_path  || exit -1 

customEcho "\n5. 輸出文件到 $ios_out_path"
rm -rf $ios_out_path
mkdir $ios_out_path


cp -r build/ios/Release-iphoneos/*/*.framework $ios_out_path
cp -r .ios/Flutter/App.framework $ios_out_path
# cp -r .ios/Flutter/engine/Flutter.framework $out
echo '輸出完成'

customEcho "\n6. 提交文件到 git"
cd $ios_project_name
git add .
git commit -m 'update lib'
git push -u origin master


customEcho "\n7. 刪除該文件夾"
cd ..
rm -rf $ios_project_name

customEcho "\nAll Done."
複製代碼

解釋就不用解釋了,上面的輸出都有寫。

這裏有一點,就是 Flutter.framework 超級大,有四五百兆,咱們把它單獨放在了一個 pod 裏,而剩下的一些每次新增插件或變動代碼都會跟着變更,因此他們是一個單獨的 pod。

也就是說,該 Flutter Module 一共有三個 git 倉庫:

  1. Flutter Module 項目的倉庫(編寫代碼等)
  2. Flutter Module 打包出來的 frameworks(不包含 Flutter.framework)
  3. Flutter.framework 倉庫

這樣的好處就是在咱們編寫完代碼,運行 sh 文件的時候,不用去下載一個四五百兆的 flutter 引擎,腳本速度提高很快,而且其餘的 iOS 項目也能夠引用。

接着改一下 flutter-lib.podspec 文件,

把這一行改爲以下:

p = Dir::open("ios_frameworks")
arr = Array.new
p.each do |f|
  if f == '.' || f == '..'
  else
    arr.push('ios_frameworks/'+f)
  end
end
s.ios.vendored_frameworks = arr
複製代碼

這樣就完成了引入全部的 frameworks。

5. 總結

到這裏 Flutter Module 就徹底引入到了現有的 iOS 工程中,關於如何運行代碼,能夠去官方文檔 - Adding a Flutter screen to an iOS app 中查找。

這樣集成的方案,感受是目前最方便的了。(若有更佳方案,煩請告知)

Flutter 端寫完代碼直接運行 ./build_module.sh 就能夠了。

iOS 端直接 pod install,超級簡單。

若有缺陷,但願你們提出,共同窗習!🤝

相關文章
相關標籤/搜索