前言:
在原有的iOS工程中,集成flutter module也是一种常见的开发模式。可以保证之前业务的稳定性,新的模块完全可以使用flutter来实现。当然中间也会涉及到很多的问题,比如 引入flutter 方式,多引擎还是单引擎,iOS和flutter怎么交互等等。
一、引入方式
第一种方案: Flutter 官方已经给出的混编方案:
文档里写的比较清楚了的,这里就不再多做赘述,大意就是说现在我们只需要在iOS工程的podfile文件中添加如下命令。
# Uncomment the next line to define a global platform for your project
flutter_application_path = '../flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
platform :ios, '13.0'
target 'Project' do
# Comment the next line if you don't want to use dynamic frameworks
# use_frameworks!
# Pods for Project
install_all_flutter_pods(flutter_application_path)
pod 'AFNetworking', '~> 4.0.1'
pod 'SDWebImage','~> 5.19.7'
pod 'Masonry', '~> 1.1.0',:inhibit_warnings => true
pod 'YYModel'
pod 'YYCategories', '~> 1.0.4'
pod 'MJRefresh', '~> 3.5.0'
pod 'SVProgressHUD'
pod 'SDCycleScrollView'
target 'ProjectTests' do
inherit! :search_paths
# Pods for testing
end
target 'ProjectUITests' do
# Pods for testing
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
end
end
flutter_post_install(installer)
end
end
然后执行 pod install 即可,这种引入方式要求每个开发的人都需要在本地电脑配置好 flutter 环境,不然是跑不起来的。这种方式相对来说对于不需要关注 flutter 模块的开发者是很头疼的,比如第一次需要打开 flutter 代码,选择依赖的 flutterSDK,然后执行 flutter pub get ,然后在进入 iOS 目录下,执行 pod install。在比如flutter模块引入新的插件了,还得按照以上流程来一遍,很麻烦。
第二种方案: iOS集成flutter的编译产物
将 flutter 以 framework 的形式通过 Cocoapods 引入 iOS 工程,iOS 只需要关注 flutter 的编译产物,不需要配置本地环境,不需要关注 flutter 代码的变化。Podfile文件如下所示,flutter 更新完后只需要执行下 pod install 即可,对象原生项目0侵入。
# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'
target 'Project' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for Project
pod 'FlutterPod',:git=>'https://gitee.com/TTGF/flutter_pod.git'
pod 'AFNetworking', '~> 4.0.1'
pod 'SDWebImage','~> 5.19.7'
pod 'Masonry', '~> 1.1.0',:inhibit_warnings => true
pod 'YYModel'
pod 'YYCategories', '~> 1.0.4'
pod 'MJRefresh', '~> 3.5.0'
pod 'SVProgressHUD'
pod 'SDCycleScrollView'
target 'ProjectTests' do
inherit! :search_paths
# Pods for testing
end
target 'ProjectUITests' do
# Pods for testing
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
end
end
end
end
1. 创建 iOS 工程
自行创建即可
2. 创建名字为‘ FlutterPod’的Pod库
$ cd ~/Desktop/(文件夹)
$ pod lib create FlutterPod
终端依次输入所需类型:
xingkunkun:FlutterForFW admin$ pod lib create MyFlutterPod
Cloning `https://github.com/CocoaPods/pod-template.git` into `MyFlutterPod`.
Configuring MyFlutterPod template.
------------------------------
To get you started we need to ask a few questions, this should only take a minute.
What platform do you want to use?? [ iOS / macOS ]
> ios
What language do you want to use?? [ Swift / ObjC ]
> objc
Would you like to include a demo application with your library? [ Yes / No ]
> no
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> none
Would you like to do view based testing? [ Yes / No ]
> no
What is your class prefix?
> Kevin
Running pod install on your new library.
创建完了之后如下图所示:
3. 在FlutterPod目录下创建 Flutter Module模块
创建完后如下图所示
4. 在 pubspec.yaml 文件中加入插件
在 pubspec.yaml 文件中加入开发所需的插件,以下是我的 pubspec.yaml 文件。
name: flutter_novel
description: "A new Flutter project."
version: 1.0.0+1
environment:
sdk: ^3.8.0
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.8
flutter_screenutil: ^5.9.3
pull_to_refresh: ^2.0.0
logger: ^1.3.0
dio: ^5.8.0+1
fluro: ^2.0.5
fluttertoast: ^8.2.12
flutter_easyloading: ^3.0.5
flutter_bloc: ^8.1.2
extended_image: ^10.0.1
status_bar_control:
git:
url: https://gitee.com/TTGF/status_bar_control.git
flutter_localizations:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
flutter:
uses-material-design: true
assets:
- assets/images/
- mock/
module:
androidX: true
androidPackage: com.example.flutter_novel
iosBundleIdentifier: com.example.flutterNovel
5. 编译
执行以下任意一个命令
$ flutter build ios --debug
或者
$ flutter build ios --release --no-codesign
会发现flutter_module 会生成一个build文件夹,里面装的就是需要的编译产物,如下图所示。
需要 debug 版本的执行 flutter build ios --debug 对应的文件夹就是 Debug-iphoneos
需要 release 版本的执行 flutter build ios --release 对应的文件夹就是 Release-iphoneos
然后将这些 framework 放在 flutter_pod 的一个文件夹里面上传 git 。
为了提高开发效率使用可以以下脚本,(自己手动操作也是没有问题的)。
在 flutter_module 模块下下创建脚本文件
$ cd ../flutter_module
$ touch compile_project.sh // 创建脚本
$ open compile_project.sh
将下面代码复制进 compile_project.sh
if [ -z $out ]; then
out='ios_frameworks'
fi
echo "准备输出所有文件到目录: $out"
echo "清除所有已编译文件"
find . -d -name build | xargs rm -rf
flutter clean
rm -rf $out
rm -rf build
source ~/.bash_profile
flutter clean
flutter pub get
addFlag(){
cat .ios/Podfile > tmp1.txt
echo "use_frameworks!" >> tmp2.txt
cat tmp1.txt >> tmp2.txt
cat tmp2.txt > .ios/Podfile
rm tmp1.txt tmp2.txt
}
echo "检查 .ios/Podfile文件状态"
a=$(cat .ios/Podfile)
if [[ $a == use* ]]; then
echo '已经添加use_frameworks, 不再添加'
else
echo '未添加use_frameworks,准备添加'
addFlag
echo "添加use_frameworks 完成"
fi
echo "编译flutter"
flutter build ios --debug
#release下放开下一行注释,注释掉上一行代码
#flutter build ios --release --no-codesign
echo "编译flutter完成"
mkdir $out
cp -r build/ios/Debug-iphoneos/*/*.framework $out
#release下放开下一行注释,注释掉上一行代码
#cp -r build/ios/Release-iphoneos/*/*.framework $out
cp -r build/ios/Debug-iphoneos/App.framework $out
cp -r build/ios/Debug-iphoneos/Flutter.framework $out
#cp -r build/ios/Release-iphoneos/App.framework $out
#cp -r build/ios/Release-iphoneos/Flutter.framework $out
echo "复制framework库到临时文件夹: $out"
libpath='../'
rm -rf "$libpath/ios_frameworks"
mkdir $libpath
cp -r $out $libpath
echo "复制库文件到: $libpath"
然后在终端执行脚本文件
$ sh compile_project.sh
就会将编译所生成的 frameworks 放在 ios_frameworks 文件夹里面。
6. 上传 git
6.1 创建仓库,建立链接。
自己操作就行了。
6.2 修改 flutter_pod 的 .gitignore 文件,注意 这是个隐藏文件。只需要上传编译产物即可,不需要上传 flutter_module 源代码。
代码如下:
# macOS
.DS_Store
# Xcode
build/
DerivedData/
*.xcworkspace/ # 注意:不要忽略整个 .xcworkspace,只忽略内部生成内容
xcuserdata/
# Carthage
Carthage/Build
# 暂时保留 Pods/ 目录的忽略,根据团队规范决定
# Pods/
#ignore flutter_module 工程文件
flutter_module/
EOF
6.3 修改 FlutterPod.podspec 文件
代码如下:
Pod::Spec.new do |s|
s.name = 'FlutterPod'
s.version = '0.1.0'
s.summary = 'A short description of FlutterPod.'
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
s.homepage = 'https://gitee.com/TTGF/flutter_pod.git'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'litingting' => '13161138626@163.com' }
s.source = { :git => 'https://gitee.com/TTGF/flutter_pod.git', :tag => s.version.to_s}
s.ios.deployment_target = '10.0'
s.static_framework = true
p = Dir::open ("ios_frameworks")
arr = Array.new
arr.push('ios_frameworks/*.framework')
s.ios.vendored_frameworks = arr
end
不然会出现识别不到 frameworks 的问题。
6.4 上传
上传就完了,无论是使用命令或者可视化软件都行。
6.5 引入使用
在Podfile 文件中 增加
pod 'FlutterPod',:git=>'https://gitee.com/TTGF/flutter_pod.git'
执行 pod install
打开 iOS 项目 如下图所示
就说明成功了,已经将编译产物引入 iOS 工程了。
这样原生开发人员,不需要配置 flutter 开发环境,再也不需要关注是否需要执行 pub get 了,不需要关注flutter 模块报错等各种问题了,每次只需要执行 pod install 即可。
二、原生代码开发
// 当使用共享引擎时,Flutter 引擎会保持之前页面的状态 initState 方法只走了一次
// 单引擎方案
// 多引擎方案
// 单引擎缓存问题
// 首次白屏问题解决(loading问题)
// 方法通信问题
// AppDelegate 中初始化的 FlutterEngine 确实会对自定义导航栏位置产生影响 (延时初始化,等到第一次使用时初始化)
// 路由方案
// 文件识别不到 因为 .gitignore 文件原因
未完待续。。。。。。