再见吧CocoaPods,Swift Package Manager(SPM)即将在Flutter 3.44中成为默认依赖管理器

长久以来Futter一直以CocoaPods为作为默认的依赖管理器,而最近就在临近Google I/O了,Flutter官方却突然宣布,从下一个Flutter稳定版3.44开始,Swift Package Manager(SPM)取代CocoaPods,成为iOS和macOS应用的默认依赖管理器。

这意味你不必再为了跑通一个App而去一顿瞎折腾Ruby环境或者安装那个令人抓狂的CocoaPods了。

Flutter这么做一方面是因为SPM是Apple官方的依赖管理器,另一方面CocoaPods实际上早进入了**维护模式,并且CocoaPods trunk 明确会在 2026-12-02 进入只读**,所以今年年底 SwiftPM 就势必会完全取代 CocoaPods 这个老古董。

终于不用再忍受那蜗牛般的pod install了......

当然这个并不突然,毕竟Flutter 支持SPM这个事早就开始实施了,我自己的项目也早早已开启了SPM模式。前段时间,我自己的开源项目还收到了支持SPM的催更请求

现在 Flutter 也开始正式提醒开发者,虽然现有版本还可以继续使用 CocoaPods,但是 2026-12-02 之后将不会在对 Pod 进行适配和支持 pod

那这对我们会有什么影响吗?

App 开发者

实际上,对于App开发者来说,Flutter的CLI会帮助你自动完成迁移处理。当你开始运行或构建 iOS 或 macOS 应用时,CLI 会自动更新 Xcode 项目使用全新的 Swift 包管理器。

如果 App 依赖的插件还没适配 SwiftPM,Flutter 会打印一条警告信息,列出所有不受支持的依赖项,同时暂时回退到 CocoaPods

当然这种回退并不会长久,毕竟Cocoapods都即将寿终正寝了,SPM又是Apple的太子,对Cocoapods的支持完全移除也在情理之中了。

当然,如果你真的遇到了SPM导致的构建问题,官方也提供了临时解决方案:

yaml 复制代码
flutter:  
 config:  
   enable-swift-package-manager: false

pubspec.yaml中把SPM关掉就好了。

插件开发者

对于插件开发者,如果你的插件支持iOS/macOS,那你是逃不开了(我不会告诉你fluwx/tobias spm适配进展缓慢)。Flutter社区其实一直在推进插件对SPM的适配(比如我就收到了适配请求),目前排名前 100 的 iOS 插件里已经有 61% 完成了迁移,后续如果没添加 Swift Package Manager 支持的 Package ,在 pub.dev 评分中得分也会被拉低。

其实是SPM与CocoaPods是非常非常不同的,这也是导致Fluwx/Tobias等项目的SPM支持进展缓慢的原因,比如说在使用CocoaPods时,podspec可以在pod install的时候作为Ruby脚本执行,即可以入侵你的Flutter项目构建过程,fluwx中的no_pay就是基于该原理实现的。而SPM虽然也是可执行的 Swift 脚本,但 SPM 在 swift package resolve 阶段就锁定了依赖图,这个阶段与 Flutter 构建流程完全解耦,无法可靠地从外部注入状态,这就导致我们无法像cocoapods那样通过在pubspec.yaml切换到no_pay状态,这意味我们又要把fluwx拆分成双包即fluwxfluwx_no_pay

且不提我的项目问题,说回SPM和CocoaPods的迁移问题。

具体怎么迁移,大家可以参考Flutter migration docs for plugin authors对插件进行迁移与适配。

过往的Cocoapods就像我上面说的一样,Cocoapods已经为我们做很多了隐式的骚操作,比如:

  • 自动把 Flutter.framework 加进来
  • 自动处理 header / linker / search path
  • 不用关心 Flutter 引擎怎么进来的

但换成SwiftPM后就不一样了:

  • SwiftPM 是完全声明式依赖系统
  • 不会有 CocoaPods 那种"魔法注入"
  • 所有依赖都必须在 Package.swift 明确写出来

要知道,我们的插件代码其实是运行在 Flutter 引擎之上的,所以你需要在 Package.swift 里加这个依赖 ,以我正在迁移的Fluwx的Package.swift为例:

less 复制代码
// swift-tools-version: 5.9
import PackageDescription


let package = Package(
    name: "fluwx",
    platforms: [.iOS("12.0")],
    products: [
        .library(name: "fluwx", targets: ["fluwx"])
    ],
    dependencies: [
         // 这是关键
        .package(name: "FlutterFramework", path: "../FlutterFramework"),
        .package(
            url: "https://github.com/JarvanMo/WechatOpenSDK-SPM", //
            from: "2.0.5"
        )
    ],
    targets: [
        .target(
            name: "fluwx",
            dependencies: [
                 // 这是关键
                .product(name: "FlutterFramework", package: "FlutterFramework"),
                .product(name: "WechatOpenSDK", package: "WechatOpenSDK-SPM")
            ],
            resources: [
                .process("Resources/PrivacyInfo.xcprivacy")
            ],
            cSettings: [
                .define("FLUWX_WITH_PAY"),
                .headerSearchPath("include")
            ],
            swiftSettings: [
                .define("FLUWX_WITH_PAY")
            ],
            linkerSettings: [
                .linkedFramework("CoreGraphics"),
                .linkedFramework("Security"),
                .linkedFramework("WebKit"),
                .unsafeFlags(["-ObjC", "-all_load"])
            ]
        )
    ]
)

另外如果在 2025 年做过迁移了插件,现在还也需要补充一个操作:在 Package.swift 文件中添加 FlutterFramework 作为依赖项,因为现在必须显式声明依赖。

Flutter 3.41 开始,要把FlutterFramework作为一个依赖: 更新一下Package.swift以引入FlutterFramework:

swift 复制代码
dependencies: [
    .package(name: "FlutterFramework", path: "../FlutterFramework")
],
targets: [
    .target(
        // TODO: Update your target name.
        name: "plugin_name",
        dependencies: [
            .product(name: "FlutterFramework", package: "FlutterFramework")
        ],

别忘记更新 Dart/Flutter 版本

yaml 复制代码
environment:
  sdk: ^3.11.0
  flutter: ">=3.41.0"

以我的切身体验来说,对 Flutter 来说这次变化影响最大的是插件生态 。以前Flutter插件都是.podspec + Podfile + pod install接入,而且有不少插件会使用到魔法注入,但迁移到SPM后,这种魔法不复存在,会使一些插件的迁移难度增加。

SPM也是完全支持Objective-C 的,只是一些支持的力度和方式不太一样,比如 SwiftPM 不允许同一个 target 里同时混放 Swift 和 C-family 源码,target 可以包含 Swift、Objective-C/C++ 或 C/C++,但单个 target 不能混合 Swift 和 C-family 语言。

旧的纯OC插件/库迁移到SPM是完全可行的,只要目录结构要符合SPM规则。

真正麻烦的是那些OC+Swift混编的工程,通常来说他们要拆成多个target......

题外话

fluwx/tobais迁移到SPM的工作还在进行中, 主要就是iOS的变动,现在没了动态化的支持,很多功能变得比较麻烦。

如果大家对插件中引用本地framework可以参考我之前的文章

那么,你准备好迎接Swift Package Manager了吗?

相关推荐
小则又沐风a3 小时前
基础的开发工具(2)---Linux
java·linux·前端
yqcoder3 小时前
JavaScript 事件流:从“捕获”到“冒泡”的完整旅程
服务器·前端·javascript
Csvn3 小时前
Vue 3 Composition API 深度解析
前端·vue.js
鹏程十八少3 小时前
11. 2026金三银四 能答对这 29 道题,你的 Android 插件化就算真正通关了
前端·后端·面试
潇凝子潇3 小时前
使用英伟达免费调用多家大模型API
java·前端·javascript
旷世奇才李先生4 小时前
Vue 3\+Vite\+Pinia实战:前端工程化与组件化开发全指南
前端·vue.js
Beginner x_u4 小时前
前端八股整理(手写 01)|Promise 超时控制、红绿灯与 Promise.all
前端·javascript·promise
万少13 小时前
Vibe Coding不停歇,移动端 TRAE SOLO 让你用手机也能编程啦
前端·javascript·后端
kyriewen1113 小时前
WebAssembly:前端界的“外挂”,让C++代码在浏览器里跑起来
开发语言·前端·javascript·c++·单元测试·ecmascript