前言
在android项目中添加flutter模块比较简单,因为毕竟都是google的,但是在ios中添加flutter模块有些麻烦了,我们首先参考的是官方文档flutter.cn/docs/develo…
但是在实际过程中会遇到各种问题(当然我本身对ios开发不熟悉也造成了不小的困扰),这里结合官方的步骤和我的经验来说说整个接入过程和遇到的坑。
我的环境是Android Studio 4.0.1 + Xcode12.4 + flutter2.0.5 (mac是M1芯片,后面会提到它的影响)
创建flutter module
首先我们创建一个flutter module的项目,可以用命令创建
flutter create --template module 项目名称
也可以直接用idea创建(注意创建的时候一定要选择flutter module)。创建完成build一下,命令如下:
flutter build ios
这里就会出现第一个问题:签名问题。执行上面命令后会报错:
No valid code signing certificates were found
You can connect to your Apple Developer account by signing in with your Apple ID
in Xcode and create an iOS Development Certificate as well as a Provisioning
Profile for your project by:
1- Open the Flutter project's Xcode target with
open ios/Runner.xcworkspace 复制代码
2- Select the 'Runner' project in the navigator then the 'Runner' target
in the project settings 复制代码
3- Make sure a 'Development Team' is selected. - For Xcode 10, look under General > Signing > Team. - For Xcode 11 and newer, look under Signing & Capabilities > Team.
You may need to: - Log in with your Apple ID in Xcode first - Ensure you have a valid unique Bundle ID - Register your device with your Apple Developer Account - Let Xcode automatically provision a profile for your app 复制代码
4- Build or run your project again
5- Trust your newly created Development Certificate on your iOS device
via Settings > General > Device Management > [your new certificate] > Trust 复制代码
For more information, please visit:developer.apple.com/library/con…AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html
Or run on an iOS simulator without code signing
这里可以在build的时候选择不签名,命令如下:
flutter build ios --no-codesign
这样就可以build成功。
创建ios项目
我们本身要在已有项目中接入,但是可以先用一个新的项目来进行调研。
这里要注意,创建ios项目的时候我的设置是:
Interfase: StoryBoard
LifeCycle: UIKit App Delegate
Language:Swift
这是因为在官方后续的示例代码中,使用AppDelegate。
这里因为我对ios开发属于小白,所以一开始选择的是SwiftUI
Interfase: SwiftUI
LifeCycle: SwiftUI App
Language:Swift
但是在后续的开发中发现SwiftUI框架好像没法启动flutter页面,于是重新创建了一个项目。
注意:我们将ios项目和之前的flutter module并列放在同一目录下,后面的操作都是基于这一相对路径的。如果你放在了不同目录,后续引入的时候就需要注意路径问题。
ios接入flutter module
官方给出了三种接入方案,这三种方案各有优缺点,我们先简单看看这三种方案:
- 使用 CocoaPods 和 Flutter SDK 集成:ios项目中用CocoaPods直接接入管理flutter module。这种方案需要所有开发人员都配置flutter环境,且安装CocoaPods;优点是通过CocoaPods自动集成,配置简单。
- 在 Xcode 中集成 frameworks:将flutter module先build成FrameWork文件,然后在ios项目中引入文件。这种方案的优点是ios开发人员不需要flutter环境,且项目不需要安装CocoaPods;缺点是每次修改都需要重新build,重新导入。
- 通过CocoaPods打包Framework:与2类似,只不过在build时加入
--cocoapods
参数:flutter build ios-framework --cocoapods --xcframework --no-universal --output=some/path/MyApp/Flutter/
。打包出来的是Flutter.podspec 文件,ios项目中通过CocoaPods管理集成。这个方案的与2方案差不多,缺点也是每次改动需要重新build,优点是ios开发人员不需要flutter环境。
所以要根据自身的情况来选择符合自己的方案。官方推荐第一种方案,我也先尝试了第一个方案。
使用 CocoaPods 和 Flutter SDK 集成
首先我们需要安装CocoaPods:
$ sudo gem install cocoapods
$ pod setup
注意: 这里网上很多文章在安装前会先让你更新ruby,配置淘宝镜像:
sudo gem update –system
gem sources –remove rubygems.org/
gem sources -a ruby.taobao.org/
gem sources -1 (验证你的ruby是淘宝)
更新这一步是没问题的,但是淘宝这个镜像就出问题了,目前这个链接已经无法访问了。所以这些老旧的信息就不要再相信了,我这边测试直接安装就可以。
然后可以根据官网guides.cocoapods.org/using/using… 来为ios项目添加CocoaPods。
首先在ios项目中执行命令:
$ pod init
这样会在ios项目中生成一个名为Podfile的文件。
然后我们修改该文件,先在开头加入:
flutter_application_path = '../flutter模块项目' load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') 复制代码
这里的flutter_application_path就是最开始创建flutter module路径,注意这个相对路径。
然后在每个target中添加:
target 'xxx' do install_all_flutter_pods(flutter_application_path) end 复制代码
最后执行:
$ pod install
CocoaPods会自动将flutter module编辑出的产物集成到ios项目中。如果没有问题,执行⌘+B 编译项目就会成功。
这里有几个问题;
M1 CPU架构导致pod install执行失败
在Finder的Application中找到Terminal(终端),右键选择info(显示简介),在info里将Open with Rosetta(使用Rosetta打开)选中。
然后重新打开终端,执行:
sudo gem install ffi
然后再执行pod install就可以了。
文件缺失
执行pod install后可以看到如下消息:
Installing Flutter (1.0.0)
Installing FlutterPluginRegistrant (0.0.1)
Installing flutter_module项目 (0.0.1)
如果缺失说明编译出了问题,我们在文章一开始创建完flutter module后就执行了flutter build进行编译,然后会在build/ios/目录下生成framework文件,CocoaPods正是将这些文件集成到ios项目中的。所以如果没有进行build,或者build失败就会导致文件缺失。
另外因为涉及到debug和release,所以我执行了两次build:
flutter build ios --no-codesign
flutter build ios --debug --no-codesign
因为第一句命令之生成了release产物。
没有FlutterPluginRegistrant
集成后编译ios不通过,报错:framework not found FlutterPluginRegistrant。但是我们并没有使用任何flutter plugin,所以不存在这个文件,但是CocoaPods不知道为什么一定要这个文件,所以导致一直编译失败。
时间有限,加上与我们的情况不符合,所以我放弃了这种集成方案。