在Podfile里尝试指定Flutter pod库的版本

3,789 阅读3分钟

image.png

在终端执行pod search Flutter,会发现Flutter在CocoaPods里其实有多个版本,但是,默认情况下,只会选择1.0.0

image.png

所以我就在想,是否能由我们自己决定用哪个Flutter pod库的版本呢?

经过一番尝试,终于成功指定了Flutter pod库的版本,但是这个方案并未在正式的项目里使用,只是我个人的一次尝试

分析Podfile

pod库的版本是在Podfile里配置的,所以这个时候,先分析一下Podfile

# 省略大部分Podfile代码,只看target的
target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end


根据将Flutter module集成到iOS项目里关于使用 CocoaPods 和 Flutter SDK集成

image.png

猜测关键代码是flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))

然后通过ruby的print语句(由于CocoaPods是由ruby实现的)找到了File.dirname所返回的路径就是项目目录下的ios

之后根据Podfile里target上面的一段代码,方法flutter_root

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

分析到一个文件路径flutter/packages/flutter_tools/bin/podhelper(这个flutter就是Flutter SDK存放路径,即环境变量FLUTTER_HOME指定的路径),打开这个文件可以看到很多代码。通过搜索Flutter找到以下代码

  # Generate a fake podspec to represent the Flutter framework.
  # This is only necessary because plugin podspecs contain `s.dependency 'Flutter'`, and if this Podfile
  # does not add a `pod 'Flutter'` CocoaPods will try to download it from the CocoaPods trunk.
  File.open(copied_podspec_path, 'w') { |podspec|
    podspec.write <<~EOF
      #
      # NOTE: This podspec is NOT to be published. It is only used as a local source!
      #       This is a generated file; do not edit or check into version control.
      #

      Pod::Spec.new do |s|
        s.name             = 'Flutter'
        s.version          = '1.0.0'
        s.summary          = 'High-performance, high-fidelity mobile apps.'
        s.homepage         = 'https://flutter.io'
        s.license          = { :type => 'MIT' }
        s.author           = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
        s.source           = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
        s.ios.deployment_target = '9.0'
        # Framework linking is handled by Flutter tooling, not CocoaPods.
        # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs.
        s.vendored_frameworks = 'path/to/nothing'
      end
    EOF
  }

  # Keep pod path relative so it can be checked into Podfile.lock.
  pod 'Flutter', :path => 'Flutter'

尝试修改s.version = '1.0.0's.version = '2.0.2'再执行pod install

成功了

image.png

这里只修改了iOS部分,其实文件里还有macOS部分,也是直接修改s.version就可以了

指定podhelper的路径

经过一番折腾,终于找到了关键的podhelper.rb文件,但这个文件在Flutter SDK里,修改了,以后所有项目都有生效,那是否能只对当前项目有效呢?通过之前的分析,发现其实可以通过修改Podfile文件里的路径,就可以指定podhelper的路径

首先,我将flutter/packages/flutter_tools/bin/podhelper.rb拷贝到当前项目目录下的ios目录,和Podfile是同级的

image.png

然后修改Podfile的内容,内容如下

# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

# 将flutter_root方法的代码移除,这个只是用来返回Flutter SDK路径的

# 这句是核心,这个是加载podhelper的路径
require File.expand_path(File.join('podhelper'))

flutter_ios_podfile_setup

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
  end
end

然后执行pod install,发现报错了,原来光修改Podfile是不行的,这样会导致podhelper.rb里的路径不对,所以还要对当前项目目录下ios里的podhelper.rb进行修改

podhelper.rb里搜索artifacts_dir =

artifacts_dir = File.join('..', '..', '..', '..', 'bin', 'cache', 'artifacts', 'engine')
# 将上面这句代码修改为下面这样
artifacts_dir = File.expand_path(File.join('bin', 'cache', 'artifacts', 'engine'),flutter_root)

# 同时加入flutter_root方法加入到podhelper.rb里flutter_additional_ios_build_settings方法之前

image.png

搜索artifacts_dir =其实有两个结果,一个是iOS的,一个是macOS的,大家按需修改或者两个都改好也可以

放上我修改好的Podfilepodhelper.rb供大家参考,传送门

版本环境

Flutter已经迭代到2.5.3了,我的这次尝试未必适合所有版本

以下是我的环境

macOS Big Sur (11.6.1)
Xcode Version 12.5.1 (12E507)

Flutter 2.5.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 18116933e7 (2 weeks ago) • 2021-10-15 10:46:35 -0700
Engine • revision d3ea636dc5
Tools • Dart 2.14.4

pod --version
1.11.2

ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]

gem --version
3.0.3