likes
comments
collection
share

iOS项目接入Flutter Module探索

作者站长头像
站长
· 阅读数 6

Flutter Module官网三种接入方式

- 方式1:使用 CocoaPods 和 Flutter SDK 集成

  都在本地安装 Flutter SDK。你的工程在每次构建的的时候,都将会从源码里编译 Flutter 模块。只需要在 Xcode 中编译应用,就可以自动运行脚本来集成 Dart 代码和插件。这个方法允许你使用 Flutter module 中的最新代码快速迭代开发,而无需在 Xcode 以外执行额外的命令,这个方法也是Flutter官网推荐的集成方法,具体步骤如下:

  1.在 Podfile 中添加下面代码

some/path/
├── my_flutter/
│   └── .ios/
│       └── Flutter/
│         └── podhelper.rb
└── MyApp/
    └── Podfile
flutter_application_path = '../my_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')

  2.每个需要集成 Flutter 的 Podfile target,执行 install_all_flutter_pods(flutter_application_path)

target 'MyApp' do
  install_all_flutter_pods(flutter_application_path)
end

  3.在 Podfile 的 post_install 部分,调用 flutter_post_install(installer)

post_install do |installer|
  flutter_post_install(installer) if defined?(flutter_post_install)
end

  总结:此集成方法需要开发者本地集成了Flutter的运行环境,集成方式比较方便,便于管理,但在Podfile中集成的路径需要明确,也就是说Flutter Module模块的代码需要和iOS项目的代码统一提交在一个仓库中,但Flutter Module的模块代码肯定是希望有自己代码仓库,并且提供多端的能力支持,所以此时会以subModule或者subTree的方式进行集成,这种在多人开发中提交维护会比较耗时耗力。

- 方式2:在 Xcode 中集成 frameworks

  除了上面的方法,你也可以创建必备的 frameworks,手动修改既有 Xcode 项目,将他们集成进去。当你组内其它成员们不能在本地安装 Flutter SDK 和 CocoaPods,或者你不想使用 CocoaPods 作为既有应用的依赖管理时,这种方法会比较合适。但是每当你在 Flutter module 中改变了代码,都必须运行 flutter build ios-framework。具体步骤如下:

  1.生成Flutter Modole产物   下面的示例假设你想在 some/path/MyApp/Flutter/ 目录下创建 frameworks:

flutter build ios-framework --output=some/path/MyApp/Flutter/

运行指令后产生的三种类型的产物如下:

some/path/MyApp/
└── Flutter/
    ├── Debug/
    │   ├── Flutter.xcframework
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework (only if you have plugins with iOS platform code)
    │   └── example_plugin.xcframework (each plugin is a separate framework)
    ├── Profile/
    │   ├── Flutter.xcframework
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework
    │   └── example_plugin.xcframework
    └── Release/
        ├── Flutter.xcframework
        ├── App.xcframework
        ├── FlutterPluginRegistrant.xcframework
        └── example_plugin.xcframework

  2.链接到项目中   在产生的产物中对应了三种类型,三种类型的使用区别可以自行搜索查阅本文不过多赘述,直接将Release中的产物拖到Targets - General 下面的 Frameworks, Libraries, and Embedded Content中,正常编译运行即可!   总结:此方式接入Flutter Module的优点是不需要开发人员安装Flutter环境的,缺点也很明显,由于不是源码接入,所以在Debug开发时调试比较困难,同时打包发布需要一些必要的手动操作来替换Framework。

- 方式3:使用 CocoaPods 在 Xcode 和 Flutter 框架中内嵌应用和插件框架

  除了将一个很大的 Flutter.framework 分发给其他开发者、机器或者持续集成 (CI) 系统之外,你可以加入一个参数 --cocoapods 将 Flutter 框架作为一个 CocoaPods 的 podspec 文件分发。这将会生成一个 Flutter.podspec 文件而不再生成 Flutter.framework 引擎文件。就像第二种集成方式那样,它将会生成 App.framework 和插件框架。步骤如下:   1.生成Flutter Modole产物   要生成 Flutter.podspec 和框架,命令行切换到 Flutter module 根目录,然后运行以下命令:

flutter build ios-framework --cocoapods --output=some/path/MyApp/Flutter/
some/path/MyApp/
└── Flutter/
    ├── Debug/
    │   ├── Flutter.podspec
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework
    │   └── example_plugin.xcframework (each plugin with iOS platform code is a separate framework)
    ├── Profile/
    │   ├── Flutter.podspec
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework
    │   └── example_plugin.xcframework
    └── Release/
        ├── Flutter.podspec
        ├── App.xcframework
        ├── FlutterPluginRegistrant.xcframework
        └── example_plugin.xcframework

  2.链接到项目中   在步骤1中生成的产物中我们可以看到既有spec文件也有xcframework文件,其中的spec文件对应的是Flutter SDK也就是Flutter的运行环境,这个环境在每次的编译中几乎不会改变,所以官网生成了一个远方的spec依赖,可以在podfile中进行远方依赖引入。

pod 'Flutter', :podspec => 'some/path/MyApp/Flutter/[build mode]/Flutter.podspec'

  其他的xcframework文件就是在业务迭代中需要经常变动的业务代码和一些三方库,这个可以继续使用方式2的集成方式进行拖入工程中引入。   总结:此方式接入Flutter Module和方式2有些类似,只是在生成的产物中由原来的~Flutter.xcframework变成了Flutter.podspec,并且引入Flutter的方式由原来的本地引入变成远程引用,也是不需要开发人员本机配置Flutter开发环境。

Flutter Module集成的最佳实践

  以上是Flutter官网提供的在iOS工程中集成Flutter Module的三种方式;在讨论Flutter Module的集成最佳实践中,需要抛出两个问题: 1、希望Flutter Module生成的产物可以不手动拖入项目,可以进行远端依赖 2、希望在Debug模块是可以直接源码调试Flutter Module模块代码,可以进行热重载

  首先看第一个问题,想让iOS集成Flutter Module可以远端依赖,这个我们可以在方式3中得到启发,方式三中使用了spec对Flutter SDK进行了远端依赖,那么我们可不可以也使用自建的spec来远程依赖.xcframework产物呢?   其实是可以的,我们可以在远端建一个仓库,名称就叫做FlutterFramewok,然后我们本地新建一个spec文件名为FlutterModuleSDK.podspec


Pod::Spec.new do |spec|
  spec.name         = "FlutterFramewok"
  spec.version      = "1.0.1"
  spec.summary      = "flutter module framework"
  spec.description  = <<-DESC
                     Flutter Module 产物
                   DESC
  spec.homepage     = "http://EXAMPLE/FlutterFramewok"
  spec.license      =  { :type => 'MIT', :file => 'LICENSE' }
  spec.platform     = :ios, "8.0"
  spec.source       = { :git => "你自己的远程仓库地址"}
  spec.requires_arc          = true
  spec.vendored_frameworks   = '*.xcframework'
end

  将方式三中生成的产物中的Release下的所有.xcframework文件同步到你的远程仓库FlutterFramewok中,之后在iOS工程目录下引入FlutterModuleSDK.podspecFlutter.podspec,我是在根目录下创建了一个单独的文件夹FlutterSpecs进行管理

some/path/MyApp/
          └──FlutterSpecs/
             └──Flutter.podspec
             └──FlutterModuleSDK.podspec
          └── Podfile

  在引入了spec文件后,可以在podFile中进行远端依赖了,如下:

pod 'FlutterModuleSDK', :podspec => './FlutterSpecs/FlutterModuleSDK.podspec'
pod 'Flutter', :podspec => './FlutterSpecs/Flutter.podspec'

  至此,第一个问题就解决了,iOS工程不需要本地依赖Framework了,所有的开发人员可以统一依赖远端仓库的Module产物以及Flutter环境,只是在远端的产物更新中稍显麻烦,不过后续也可以通过脚本进行远端仓库的更新操作。   那么对于第二个问题,想要在Debug环境下进行源码热更新调试,该怎么实现呢?其实我们可以使用方式1中的pod集成来进行debug环境下的热更新调试,只是需要一个开关来控制下即可。在podFile中使用enable_flutter来手动控制Flutter Module的集成方式,当在开发业务时,需要源码的热更新功能,此时可以设置enable_fluttertrue,当需要打包时可以设置enable_flutterfalse


platform :ios, '12.0'

# 支持源码调试开关
$enable_flutter = false

if $enable_flutter

  flutter_application_path = 'Flutter Module在你电脑上的绝对路径(这里的每个开发人员的路径会不一样,不要求统一,只要路径正确就可以)'
  
  load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
  
end

target 'MyApp' do
  #添加源码调试开关
  if $enable_flutter
  
    install_all_flutter_pods(flutter_application_path)
    
  else
  
    pod 'FlutterModuleSDK', :podspec => './FlutterSpecs/FlutterModuleSDK.podspec'
    
    pod 'Flutter', :podspec => './FlutterSpecs/Flutter.podspec'
    
  end

end

开关打开时,可以使用VSCode打开Flutter Module模块,使用Attach to Flutter on Device来进行断点、热更新等相关调试了。 iOS项目接入Flutter Module探索

参考资料: