flutter_notes
flutter_notes copied to clipboard
Flutter & flutter_boost开发iOS混合开发项目问题记录;iOS远程依赖Flutter Module组件代码;
2022年临时补充:
可以把构建产物的中Flutter.podspec文件放到文件服务器上,这样就可以远程依赖Flutter.xcframework;其它的xcframework产物都放一个git仓库(对应一个podspec/组件库)管理,每次构建打个tag,iOS侧同样是远程依赖这个组件库。
目录
- 在iOS项目依赖FlutterModule组件代码
- iOS项目依赖Flutter Module方案汇总
- 构建脚本
- 相关脚本
- 内嵌依赖的xcframework和pod依赖的第三方库重复冲突,新版Xcode编译失败
- flutter_boost混合开发挖坑记录
- 问题1.首次进入Flutter页面出现空白
- 问题2.在原生页面切换深浅色后进入Flutter页面会先渲染上一次的配色模式
- 问题3. 自定义Flutter(Boost)容器后,Flutter页面退出后没有调用dispose,出现内存泄漏
这个仓库主要有2部分,整理了如何在iOS项目导入FlutterModule组件代码,以及整理开发过程中遇到的一些问题和对应的解决方案。
在iOS项目依赖FlutterModule组件代码
依赖Flutter组件代码的分为本地依赖、远程依赖2种。下面介绍的前3种是本地依赖,同时也是官方推荐的方法,在开发文档Adding Flutter to iOS 有详细介绍。简单的说本地依赖就是直接依赖本机的编译产物,需要每个开发人员都安装Flutter开发环境,同时编译产物会导出到FlutterModule或者iOS项目的Git目录下,依赖指向的也是相对路径,加上Flutter版本不一致就容易造成Git冲突。远程依赖则是将Flutter编译得到的相关framework都推到云端git,在iOS项目通过CocoaPods远程依赖,也就不用要求所有人都安装Flutter开发环境,Flutter Module 、Flutter编译产物、Native 都有独立的Git,某端的更改不会直接影响到另一端。
iOS项目依赖Flutter Module方案汇总
- 1.基于CocoaPods和podhelper.rb脚本本地依赖FlutterModule
- 2.编译FlutterModule,手动添加.xcframwork到iOS项目中
- 3.编译FlutterModule,远程依赖Flutter.xcframework,本地依赖其余.xcframwork
- 4.远程依赖Flutter Module组件库编译产物(简单版)
- 5.在iOS项目远程依赖FlutterModule组件库代码(5个可行方案)
- 6.远程依赖Flutter Module产物 + Git Submodule + Shell脚本 (升级版 )
构建脚本
脚本基于远程依赖Flutter Module组件库编译产物 方案0x05实现,但同样适用于远程依赖Flutter Module组件库编译产物(升级版 )。
实现了Futter编译到产物分拣上传的功能,其它的方案也可以参考这个脚本。
相关脚本
将Flutter组件库添加到iOS项目中,流程中会涉及到2个关键脚本,一个ruby脚本podhelper.rb, 另一个是shell脚本xcode_backend.sh,我看的时候加了一些注解。
- podhelper.rb 脚本注解,此脚本主要的功能是导入Flutter、App、FlutterPluginRegistrant和其它第三方库的本地依赖,另外设置一个Build Phases执行脚本,在编译Xcode项目时执行xcode_backend.sh脚本。
- xcode_backend.sh 脚本注解,此脚本的主要功能是根据编译模式和CPU架构 编译/合成 Flutter相关的framework动态库。
- 待研究:
flutter build ios-framework对应的源码,路径是flutter/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
内嵌依赖的xcframework和pod依赖的第三方库重复冲突,新版Xcode编译失败
FlutterPluginSDK里面的xcframework和iOS项目原本pod依赖的第三方库重复依赖,编译失败,提示:Multiple commands produce '.framework'。比如Flutter侧依赖的插件依赖了FMDB,编译Flutter后就导出了FMDB.scframework,按照远程依赖的构建方案,FMDB.xcframework会集成到FlutterPluginSDK里,同时iOS项目种也有其它的组件库依赖了FMDB。应该是在“[CP] Embed Pods Frameworks”编译阶段也导出了内嵌的FMDB.frameowork,跟FlutterPluginSDK里面的framework重复了,由于新版Xcode编译时默认使用了New Build System,编一阶段frameowrk重建时会抛出异常multiple commands produce framework。
Multiple commands produce '/Users/user/Library/Developer/Xcode/DerivedData/MyProj-flazyqyatfvrvsgcoofvwrizuvot/Build/Products/Debug-iphoneos/MyProj.app/Frameworks/FMDB.framework':
1) That command depends on command in Target 'MyProj' (project 'MyProj'): script phase “[CP] Embed Pods Frameworks”
2) That command depends on command in Target 'MyProj' (project 'MyProj'): script phase “[CP] Embed Pods Frameworks”
Multiple commands produce '/Users/user/Library/Developer/Xcode/DerivedData/MyProj-flazyqyatfvrvsgcoofvwrizuvot/Build/Products/Debug-iphoneos/MyProj.app/Frameworks/MMKV.framework':
1) That command depends on command in Target 'MyProj' (project 'MyProj'): script phase “[CP] Embed Pods Frameworks”
Multiple commands produce ...
这个问题我以前也遇到过,因为Today Target和主工程的Pod都依赖了同一个库,编译时也报这个错误。Build System Release Notes for Xcode 10 有相关的介绍。
我目前尝试的可行方案有2种,其它的我没有试了。
-
- 选择旧的构建系统,具体的操作路径:
Xcode -> File -> WorkSpace Settings -> Build System -> Legacy Build Sysyte
- 选择旧的构建系统,具体的操作路径:
-
- 新的构建系统,但是避免重复依赖,从
FlutterPluginSDK删除掉重复依赖的xcframework。我已经在构建脚本 flutter_build_script.sh中加了黑名单,把需要删除的xcframework加到黑名单即可。
- 新的构建系统,但是避免重复依赖,从
flutter_boost混合开发挖坑记录
我们的项目使用flutter_boost来实现iOS & Flutter混合项目开发,目前也已经适配到flutter_boost v3.0.0。FlutterBoost在3.0.0新增一个Flutter控制器容器,但我们项目有统一的控制器基类,为了统一控制器页面的某些特性和接口功能, 我在FlutterBoost的容器上又封装了一层控制器容器,导致在开发过程遇到了深浅色适配和内存泄漏的问题。
深浅色适配和Push/Present进入Flutter页面是我在项目开发中真实用到的场景,在Demo中我还原了这2个场景及遇到的问题,给原生页面和Flutter页面都适配了深浅色,其中的搜索页SearchPage就是Flutter页面,而APP的主页就是原生页面(可以切换深浅色),另外进入SearchPage采用了Push、Present 2种转场方式,以对比效果。
另外我在FBFlutterViewContainer 基础上自定义一个Flutter控制器容器,最后所有的Flutter页面都由FlutterModuleViewController承载,而FBFlutterViewContainer则添加在容器FlutterModuleViewController上,但是2者不是继承关系,而是父子控制器的关系。之所以这么做是为了统一控制器页面的某些特性和接口功能。
FlutterModuleViewController.m
self.flutterContainer.view.frame = self.view.bounds;
[self.view insertSubview:self.flutterContainer.view atIndex:0];
[self addChildViewController:self.flutterContainer];

问题1.首次进入Flutter页面出现空白
首次进入Flutter页面,由于Flutter预热时会出现短暂的空白,点击查看细节和解决方案

问题2.在原生页面切换深浅色后进入Flutter页面会先渲染上一次的配色模式
Flutter适配深浅色后在切换深浅色模式时出现渲染异常,点击查看细节和解决方案
问题3. 自定义Flutter(Boost)容器后,Flutter页面退出后没有调用dispose,出现内存泄漏
由于我在FBFlutterViewContainer 基础上自定义了Flutter控制器容器,导致在退出页面时没有触发notifyWillDealloc,致使Flutter页面没有得到释放。点击查看细节和解决方案
回到顶部🔝