flutter —— 理解 iOS 的依赖管理
下载依赖
可以通过以下命令生成 iOS 配置文件:
flutter build ios --config-only
等价于传统的方式:
flutter pub get
cd ios
pod install
pod install 做了什么?
- 执行
ios/Podfile(本质是一个 Ruby 脚本)。 - Podfile 会引入 Flutter SDK 目录下的
packages/flutter_tools/bin/podhelper.rb,并调用:flutter_install_all_ios_pods方法flutter_install_plugin_pods方法
最终生成 Pod 注册信息与符号链接 ios/.symlinks/plugins(指向用户目录下的.pub-cache)。
- 根据 Pod 注册信息找到对应的
.podspec文件。 - 生成 Pods/ 目录,包含 Xcode Target 和构建设置,更新
Podfile.lock,完成依赖安装。
PS:CocoaPods 的“安装”只是准备源码和 Xcode Target,方便后续编译,并不生成独立的二进制文件。
PS: android 是通过 android/settings.gradle 文件中引入的 dev.flutter.flutter-plugin-loader,自动扫描项目根目录的 .flutter-plugins-dependencies 实现的相关依赖的下载。
podhelper.rb 核心源码说明
flutter_install_plugin_pods 方法流程如下:
def flutter_install_plugin_pods(application_path = nil, relative_symlink_dir, platform)
# 获取项目路径
application_path ||= File.dirname(defined_in_file.realpath) if respond_to?(:defined_in_file)
raise 'Could not find application path' unless application_path
# 准备 symlinks 目录,避免 Podfile.lock 出现开发者绝对路径
symlink_dir = File.expand_path(relative_symlink_dir, application_path)
system('rm', '-rf', symlink_dir)
symlink_plugins_dir = File.expand_path('plugins', symlink_dir)
system('mkdir', '-p', symlink_plugins_dir)
# 读取插件依赖信息
plugins_file = File.join(application_path, '..', '.flutter-plugins-dependencies')
dependencies_hash = flutter_parse_plugins_file(plugins_file)
plugin_pods = flutter_get_plugins_list(dependencies_hash, platform)
swift_package_manager_enabled = flutter_get_swift_package_manager_enabled(dependencies_hash, platform)
plugin_pods.each do |plugin_hash|
plugin_name = plugin_hash['name']
plugin_path = plugin_hash['path']
has_native_build = plugin_hash.fetch('native_build', true)
# 判断 iOS/macOS 共享代码路径
shared_darwin_source = plugin_hash.fetch('shared_darwin_source', false)
platform_directory = shared_darwin_source ? 'darwin' : platform
next unless plugin_name && plugin_path && has_native_build
# 在 .symlinks/plugins 下生成符号链接
symlink = File.join(symlink_plugins_dir, plugin_name)
File.symlink(plugin_path, symlink)
relative = flutter_relative_path_from_podfile(symlink)
# Swift Package Manager 情况处理
swift_package_exists = File.exist?(File.join(relative, platform_directory, plugin_name, "Package.swift"))
next if swift_package_manager_enabled && swift_package_exists
# 如果插件只支持 SPM 而不支持 CocoaPods,则跳过
next if swift_package_exists && !File.exist?(File.join(relative, platform_directory, plugin_name + ".podspec"))
# 注册 Pod 信息,CocoaPods 会根据这个解析 .podspec 并生成 Pods/
pod plugin_name, path: File.join(relative, platform_directory)
end
end
核心要点总结
.symlinks/plugins用于统一管理插件路径,保证 Podfile.lock 中使用相对路径。- 支持 iOS 和 macOS 的共享代码(
darwin目录)。 - 对 Swift Package Manager 插件做了跳过处理,避免冲突。
- 最终由 CocoaPods 根据注册信息解析
.podspec并生成Pods/目录。
浙公网安备 33010602011771号