Flutter - 将 Flutter 集成到现有项目(iOS - Framework篇)
source link: http://mp.weixin.qq.com/s?__biz=MzU4NzkzMDkxMw%3D%3D&%3Bmid=2247483977&%3Bidx=1&%3Bsn=3a286e7fec8eb5cb5746bc3df55598b9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
本篇文章大幅参考了 caijinglong 大佬的总结文章: 把flutter作为framework添加到已存在的iOS中 [1]
用 Flutter 来开发,从来都不可能是新开的一个纯 Flutter 项目,很大一部分都是 老项目接入 Flutter 来混编。
在 Flutter 官网 - Adding to an iOS app [2] 这里,官方也给出了一些将 Flutter 集成进入现有 iOS 项目的方法。但是,这些都多多少少的不符合我们的需求。
1. 从 Flutter Module 说起
想要把 Flutter 集成进现有 iOS 项目,我们就必须使用 Flutter Module 。
那就先用命令创建一个 Flutter Module: flutter create --template module flutter_test_module
Flutter APP 和 Flutter Module 的不同之处在于 pubspec.yaml
最后一段:
# 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 里。
这里面设置了是否使用 androidx,Android 和 iOS 的 APP id。
2. iOS原生项目所需的文件
先说一下,iOS 原生项目引入 Flutter Module 需要如下 Framework:
1. Flutter.framework 2. App.framework 3. FlutterPluginRegistrant.framework (如果有用到原生的插件 - 非纯 dart 编写) 4. Pods_Runner.framework(如果有用到原生的插件 - 非纯 dart 编写) 5. *.framework(插件的 framework)
下面继续集成。
Flutter Module 创建完成后,先来给 iOS 打个包,命令如下: flutter build ios --release --no-codesign
。
然后看一下打包出来的东西,路径为 build->ios->Release-iphoneos
:
如果有第三方库的话,这里面应该是有上面说的 3、4、5 的 framework,但是我们刚创建项目,什么都没有加,所以是没有任何 framework的。
然后去 .ios/Flutter
里找 1、2:
但是我们写程序不可能什么插件都不用,所以加上一个 shared_preferences [3] ,再来打包看一下 build 文件夹:
可以看到确实出现了我们上面说的 3、4、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]
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 [5] 中查找。
这样集成的方案,感觉是目前最方便的了。(如有更佳方案,烦请告知)
Flutter 端写完代码直接运行 ./build_module.sh
就可以了。
iOS 端直接 pod install
,超级简单。
如有缺陷,希望大家提出,共同学习!
References
[1]
把flutter作为framework添加到已存在的iOS中: https://www.kikt.top/posts/flutter/exists/add-flutter-to-ios/
[2]
Flutter 官网 - Adding to an iOS app: https://flutter.dev/docs/development/add-to-app/ios/project-setup
[3]
shared_preferences: https://pub.dev/packages/shared_preferences
[4]
caijinglong 大佬的博客查看解决办法。: https://www.kikt.top/posts/flutter/exists/add-flutter-to-ios/#使用-cocoapod-管理原生工程
[5]
官方文档 - Adding a Flutter screen to an iOS app: https://flutter.dev/docs/development/add-to-app/ios/add-flutter-screen?tab=vc-objective-c-tab
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK