Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

Latest commit

 

History

History
126 lines (69 loc) · 10.1 KB

README.md

File metadata and controls

126 lines (69 loc) · 10.1 KB

2022年临时补充:
可以把构建产物的中Flutter.podspec文件放到文件服务器上,这样就可以远程依赖Flutter.xcframework;其它的xcframework产物都放一个git仓库(对应一个podspec/组件库)管理,每次构建打个tag,iOS侧同样是远程依赖这个组件库。

  目录

这个仓库主要有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方案汇总

构建脚本

脚本基于远程依赖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 Frameworks2) 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 FrameworksMultiple commands produce ...

这个问题我以前也遇到过,因为Today Target和主工程的Pod都依赖了同一个库,编译时也报这个错误。Build System Release Notes for Xcode 10 有相关的介绍。

我目前尝试的可行方案有2种,其它的我没有试了。

    1. 选择旧的构建系统,具体的操作路径: Xcode -> File -> WorkSpace Settings -> Build System -> Legacy Build Sysyte
    1. 新的构建系统,但是避免重复依赖,从FlutterPluginSDK删除掉重复依赖的xcframework。我已经在构建脚本 flutter_build_script.sh中加了黑名单,把需要删除的xcframework 加到黑名单即可。

flutter_boost混合开发挖坑记录

我们的项目使用flutter_boost来实现iOS & Flutter混合项目开发,目前也已经适配到flutter_boost v3.0.0FlutterBoost3.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];

Flutter控制器容器

问题1.首次进入Flutter页面出现空白

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

问题图

问题2.在原生页面切换深浅色后进入Flutter页面会先渲染上一次的配色模式

Flutter适配深浅色后在切换深浅色模式时出现渲染异常,点击查看细节和解决方案

问题3. 自定义Flutter(Boost)容器后,Flutter页面退出后没有调用dispose,出现内存泄漏

由于我在FBFlutterViewContainer 基础上自定义了Flutter控制器容器,导致在退出页面时没有触发notifyWillDealloc,致使Flutter页面没有得到释放。点击查看细节和解决方案

回到顶部🔝