Swift 包管理器 (SPM) 入门指南 – wiki基地


Swift 包管理器 (SPM) 入门指南:现代 Swift 开发的基石

在现代软件开发中,高效地管理项目依赖是至关重要的。无论是引入第三方库以利用现有功能,还是将自己的代码组织成可复用的模块,一个强大的包管理器都能极大地提升开发效率和项目可维护性。对于 Swift 生态系统来说,Swift Package Manager (SPM) 正扮演着这样的核心角色。

SPM 是苹果官方推出的,深度集成于 Swift 工具链的依赖管理工具。它不仅让 Swift 项目能够方便地引入外部依赖,也为 Swift 代码库的构建、测试和分发提供了标准化的流程。如果你正在进行 Swift 开发,无论是构建 iOS/macOS 应用、服务器端应用还是命令行工具,掌握 SPM 都是一项必备技能。

本文将为你提供一份全面的 SPM 入门指南,从基本概念到实际操作,带你一步步走进 Swift 包管理器的世界。

1. 为什么选择 Swift Package Manager?

在 SPM 出现之前,Swift 开发者主要依赖 Carthage 和 CocoaPods 这两个第三方依赖管理器。它们各自有优点和缺点:

  • CocoaPods: 功能强大,社区活跃,依赖解决能力强,支持动态库和静态库,但需要额外的 Ruby 环境安装,且对项目文件(.xcodeproj)的修改较多,可能引入冲突。
  • Carthage: 更轻量,只负责构建和提供二进制文件,对项目文件修改少,但配置相对复杂,且不负责依赖的传递性管理(需要手动添加所有直接和间接依赖)。

SPM 作为官方解决方案,旨在结合两者的优点并提供更原生的体验:

  • 原生集成: SPM 直接集成在 Swift 编译器和 Xcode 中,无需额外安装第三方工具(除了 Swift/Xcode 本身)。
  • 简单易用: 无论是添加依赖还是创建自己的包,流程都相对直观。
  • 跨平台支持: SPM 是 Swift 工具链的一部分,可以在 macOS、Linux 等支持 Swift 的平台上使用,对于服务器端 Swift (如 Vapor, Kitura) 或跨平台命令行工具开发尤其重要。
  • 自动化管理: SPM 负责依赖的下载、构建、链接,以及依赖关系的解析和冲突解决。
  • 高性能: 原生集成通常意味着更好的构建性能,且 SPM 有自己的缓存机制。
  • 标准化: 提供了一套标准的项目结构和描述格式 (Package.swift),使得 Swift 代码的组织和分享更加统一。
  • 确定性: 使用 Package.resolved 文件锁定依赖的具体版本,确保团队成员或在不同时间构建时使用相同的依赖版本,避免“在我机器上可以”的问题。

总而言之,SPM 是苹果和 Swift 社区推荐的现代 Swift 项目依赖管理方式,学习和使用它是迈向更高效、更标准的 Swift 开发的关键一步。

2. 前置条件

开始使用 SPM,你需要:

  1. 安装 Swift 工具链: 通常通过安装最新版本的 Xcode 来获得,Xcode 包含了 Swift 编译器和 SPM。
  2. 终端 (Terminal): 虽然 Xcode GUI 可以完成大部分操作,但了解并使用命令行工具 (swift package) 对于自动化、脚本编写或在非 GUI 环境下工作非常有用。

SPM 对项目结构有一定要求,但 Xcode 创建的新项目通常都满足这些要求。

3. 如何将 Swift 包添加到你的项目(消费者视角)

最常见的 SPM 使用场景是作为库的消费者,将现有的 Swift 包集成到你的应用或框架中。SPM 支持将包添加到应用项目 (.xcodeproj.xcworkspace) 或另一个 Swift 包中。

3.1 在 Xcode 中添加包 (推荐方式)

Xcode 提供了非常便捷的 GUI 界面来管理 SPM 依赖。

  1. 打开你的项目: 在 Xcode 中打开你的 .xcodeproj.xcworkspace 文件。
  2. 添加包:

    • 选择菜单栏 File -> Add Packages...
    • 或者,在项目导航器 (Project Navigator) 中,选择你的项目文件(顶部的蓝色图标),然后在项目设置 (Project Settings) 视图中,选择 Package Dependencies 标签页,点击底部的 + 按钮。
  3. 输入包仓库 URL: 在弹出的搜索框中,输入你想要添加的 Swift 包的 Git 仓库 URL。这个 URL 通常是 HTTPS 格式,例如 https://github.com/Alamofire/Alamofire.git。输入后,Xcode 会自动查找该仓库。

  4. 选择依赖规则 (Dependency Rule): 找到包后,你需要指定你想要使用的版本。SPM 提供了几种灵活的规则:

    • Version (Up to Next Major): 使用指定版本(如 5.0.0)或其之后的所有版本,直到下一个主版本更新之前(即会接受 5.x.y 但不会接受 6.0.0)。这是最常用的推荐选项,因为它允许你自动获取 bug 修复和新特性(在 minor 或 patch 版本中),同时避免引入可能包含重大变更的主版本。
    • Version (Up to Next Minor): 使用指定版本(如 5.8.0)或其之后的所有版本,直到下一个次要版本更新之前(即会接受 5.8.x 但不会接受 5.9.0)。比上一个更保守。
    • Version (Exact): 只使用指定的精确版本(如 5.8.1)。最保守,确保版本完全一致,但不会自动获取任何更新。
    • Branch: 使用特定分支的最新提交。通常用于开发或测试阶段,不推荐用于生产环境,因为分支 HEAD 随时可能变化,导致构建不确定。
    • Commit: 使用特定提交的哈希值。提供最高的确定性,但如果你需要更新包,必须手动修改提交哈希。通常用于锁定到一个已知的稳定状态。

    根据你的需求选择合适的规则。对于初学者和大多数应用开发,”Up to Next Major Version” 是一个很好的起点。

  5. 添加包到目标 (Add to Target): 在窗口的底部,Xcode 会显示包中的产品 (Products) 和你项目中的目标 (Targets)。一个包可以包含一个或多个库 (Libraries) 或可执行文件 (Executables) 作为其产品。你需要选择将包的哪些产品链接到你项目中的哪个目标。例如,如果你添加的是 Alamofire,它可能只有一个名为 Alamofire 的库产品。你需要勾选你想要使用 Alamofire 的那个应用或框架目标。

  6. 完成添加: 点击 Add Package 按钮。

Xcode 此时会开始下载依赖并解析依赖关系。这个过程可能需要一些时间,取决于你的网络速度和依赖的数量。下载的包会存储在你的主目录下的一个共享缓存中 (~/Library/Caches/org.swift.swiftPM/),以便不同项目可以复用。

成功添加后,你会看到:

  • 在项目导航器的 Package Dependencies 部分出现了你添加的包。
  • 在项目的 Package Dependencies 标签页中列出了所有已添加的包及其版本规则。
  • Xcode 会自动生成或更新一个 Package.resolved 文件(通常位于 .xcodeproj.xcworkspace 同级目录下),该文件精确记录了每个依赖(包括传递性依赖)被解析到的具体版本。务必将 Package.resolved 文件添加到你的版本控制中 (如 Git),以确保团队成员和构建系统都能构建出相同的版本。

3.2 在代码中使用导入的包

一旦包被成功添加到你的目标,你就可以在 Swift 代码中像使用任何模块一样使用它了。只需在你需要使用该包的代码文件的顶部添加 import PackageName 语句即可,例如 import Alamofire。然后你就可以调用该库提供的类型和函数了。

3.3 使用命令行管理依赖 (进阶)

虽然 Xcode GUI 方便,但了解命令行对于自动化或调试很有帮助。在你的项目根目录(包含 .xcodeprojPackage.swift 文件)中,可以使用 swift package 命令:

  • 编辑依赖: 要手动修改 Package.swift 文件来添加或修改依赖,然后运行 swift package resolve 来解析和下载依赖,并更新 Package.resolved
  • 更新依赖: 运行 swift package update。这会尝试根据 Package.swift 中定义的规则,更新依赖到最新的兼容版本,并更新 Package.resolved
  • 清理构建文件: 运行 swift package clean 可以清理之前构建生成的中间文件。

如果你是为一个纯 SPM 包(没有 .xcodeproj)添加依赖,你将直接编辑该包的 Package.swift 文件,并在 dependencies 数组中添加新的依赖。

swift
// 示例 Package.swift 文件片段
let package = Package(
name: "MyProject",
dependencies: [
// 添加 Alamofire 依赖
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.8.1"),
// 添加另一个依赖
.package(url: "https://github.com/SnapKit/SnapKit.git", .upToNextMajor(from: "5.0.0"))
],
targets: [
// ... targets 定义
]
)

添加或修改 Package.swift 后,在终端中运行 swift package resolve 或在 Xcode 中构建项目,SPM 就会处理新的依赖。

4. 如何创建你自己的 Swift 包(生产者视角)

除了使用别人的包,你也可以创建自己的 Swift 包来组织代码,供自己其他项目使用或分享给社区。

4.1 使用命令行创建包 (推荐方式)

命令行是创建标准 Swift 包最快捷的方式。

  1. 打开终端: 导航到你想要创建包的父目录。
  2. 创建包: 使用 swift package init 命令:
    • 创建库 (Library): swift package init --type library
      • 这是最常见的类型,用于创建可被其他项目导入和使用的代码模块。
    • 创建可执行文件 (Executable): swift package init --type executable
      • 用于创建可以独立运行的命令行工具。
    • 创建空包 (Empty): swift package init --type empty
      • 创建一个只有 Package.swift 文件的空包,适用于手动配置复杂结构。

例如,要创建一个名为 MyAwesomeLibrary 的库:
bash
cd /path/to/your/development/folder
swift package init --type library --name MyAwesomeLibrary

SPM 会为你生成以下标准目录结构:

MyAwesomeLibrary/
├── Sources/
│ └── MyAwesomeLibrary/
│ └── MyAwesomeLibrary.swift # 默认生成的源文件
├── Tests/
│ └── MyAwesomeLibraryTests/
│ └── MyAwesomeLibraryTests.swift # 默认生成的测试文件
├── .gitignore
└── Package.swift # 包的清单文件

4.2 使用 Xcode 创建包

你也可以通过 Xcode GUI 创建 Swift 包:

  1. 选择菜单栏 File -> New -> Package...
  2. 填写包名称,选择存储位置。
  3. 选择包类型 (Library 或 Executable)。
  4. 勾选是否包含单元测试。
  5. 点击 Create

Xcode 也会生成类似的目录结构,并在 Xcode 中打开该包。

4.3 理解生成的结构

  • Package.swift: 这是包的清单文件,使用 Swift 语言编写。它定义了包的名称、平台支持、产品、依赖以及最重要的——目标 (Targets)。你需要在这里声明你的代码是如何组织的。
  • Sources/: 这个目录包含了你的包的实际源代码。按照 SPM 的约定,Sources 下的每个子目录通常对应一个目标 (Target)。例如,Sources/MyAwesomeLibrary/ 包含了 MyAwesomeLibrary 目标的代码。
  • Tests/: 这个目录包含了你的包的单元测试代码。同样,Tests 下的每个子目录通常对应一个测试目标,并对应于一个源代码目标。例如,Tests/MyAwesomeLibraryTests/ 包含了测试 MyAwesomeLibrary 目标的代码。SPM 使用 XCTest 框架进行测试。
  • .gitignore: 一个标准的 Git 忽略文件,忽略 SPM 生成的构建文件和缓存。

5. Package.swift 文件详解

Package.swift 是 Swift 包的灵魂,它是一个 Swift 文件,定义了包的所有元数据和结构。它使用 PackageDescription 模块提供的 API 来描述包的各个方面。

以下是一个典型的 Package.swift 文件结构:

“`swift
// swift-tools-version: 5.9 // 指定 Swift 工具链版本

import PackageDescription

let package = Package(
// 1. 包名称
name: “MyAwesomeLibrary”,

// 2. 支持的平台 (可选)
// 如果是用于应用开发,建议指定最低平台版本
platforms: [
    .macOS(.v10_15),
    .iOS(.v13),
    .tvOS(.v13),
    .watchOS(.v6),
    .visionOS(.v1),
],

// 3. 产品 (Products) - 定义包对外暴露的内容
products: [
    // 定义一个库产品
    .library(
        name: "MyAwesomeLibrary", // 产品名称
        targets: ["MyAwesomeLibrary"] // 包含哪些目标 (Targets)
        // libraryKind: .static or .dynamic (可选,默认通常由构建系统决定)
    ),
    // 如果是可执行包,可以定义一个可执行产品
    // .executable(
    //     name: "mycommandlineapp",
    //     targets: ["mycommandlineapp"]
    // )
],

// 4. 依赖 (Dependencies) - 定义包依赖的外部 SPM 包
dependencies: [
    // 依赖一个远程 Git 仓库的包
    .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.8.1"),
    // 依赖另一个远程 Git 仓库的包,使用不同的版本规则
    .package(url: "https://github.com/SnapKit/SnapKit.git", .upToNextMajor(from: "5.0.0")),
    // 依赖本地路径的包 (用于开发调试)
    // .package(path: "../AnotherLocalPackage")
],

// 5. 目标 (Targets) - 定义包内部的代码模块
targets: [
    // 源代码目标 (Library Target)
    .target(
        name: "MyAwesomeLibrary", // 目标名称
        dependencies: [
            // 该目标依赖包内部的其他目标 或 外部依赖包的产品
            .product(name: "Alamofire", package: "Alamofire"), // 依赖 Alamofire 包的 Alamofire 产品
            // .target(name: "AnotherInternalTarget"), // 依赖包内的另一个目标
        ],
        path: "Sources/MyAwesomeLibrary", // 源代码路径 (相对于 Package.swift)
        resources: [ // 包含资源文件 (如图片、json等)
             .process("Resources") // 处理 Resources 目录下的所有资源
             // .copy("SomeSpecificFile.txt") // 复制指定文件
        ],
        // swiftSettings: [...], // Swift 编译器设置
        // linkerSettings: [...], // 链接器设置
        // plugins: [...] // 构建插件
    ),

    // 测试目标 (Test Target)
    .testTarget(
        name: "MyAwesomeLibraryTests", // 测试目标名称
        dependencies: [
            // 测试目标通常依赖它要测试的源代码目标
            .target(name: "MyAwesomeLibrary"),
            // 测试框架依赖 (如 Swift-Snapshot-Testing)
            // .product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
        ],
        path: "Tests/MyAwesomeLibraryTests" // 测试代码路径
        // resources: [...] // 测试资源
    )

    // 如果有多个源代码模块,可以定义更多 target
    // .target(
    //    name: "AnotherInternalTarget",
    //    dependencies: [...]
    //    path: "Sources/AnotherInternalTarget"
    // )
]

)
“`

让我们详细 breakdown 每个部分:

  • swift-tools-version:: 必须在文件顶部以注释的形式指定,告诉 SPM 使用哪个版本的工具链来解析这个 Package.swift 文件。随着 SPM 的发展,Package.swift 的语法和支持的功能也会更新,指定版本可以确保向后兼容性。
  • import PackageDescription: 导入 SPM 定义包结构的模块。
  • let package = Package(...): 创建一个 Package 实例,包含了包的所有配置。
    • name: 包的名称,必需。
    • platforms: (可选)指定该包支持的最低平台版本。这对于面向特定平台(如 iOS, macOS)的库非常重要,确保使用者不会在旧版本系统上引入不兼容的代码。如果你的包是纯 Swift 逻辑,不依赖特定平台 API,可以省略此项。
    • products: 定义包构建完成后可以对外提供的可执行单元。主要有两种类型:
      • .library: 一个库,可以被其他包或应用依赖。你可以指定 name 和它包含的 targets。库可以是静态的 (.static) 或动态的 (.dynamic),不指定时 SPM 或 Xcode 会根据使用场景和依赖关系自动决定。
      • .executable: 一个可执行文件,可以独立运行。通常只有一个目标。
        一个包可以定义多个产品。
    • dependencies: 定义该包所依赖的外部 SPM 包。使用 .package 语法,指定包的 Git 仓库 URL 和版本规则。
      • .package(url: String, from: Version): 指定 URL 和一个最低版本号。SPM 会使用该版本或更高兼容版本(取决于工具链版本和依赖规则)。
      • .package(url: String, .upToNextMajor(from: Version)): 指定 URL 和一个最低版本号,接受该版本及之后的所有次要/补丁版本,直到下一个主版本。
      • .package(url: String, .upToNextMinor(from: Version)): 指定 URL 和一个最低版本号,接受该版本及之后的所有补丁版本,直到下一个次要版本。
      • .package(url: String, .exact(Version)): 只接受指定的精确版本。
      • .package(url: String, .branch(String)): 依赖特定分支的最新提交。
      • .package(url: String, .revision(String)): 依赖特定提交哈希。
      • .package(path: String): 依赖本地文件系统路径上的另一个包,用于本地开发和测试。
    • targets: 包的核心,定义了实际的代码模块和它们的构建方式。一个包可以有多个目标。主要类型:
      • .target: 一个源代码模块,可以是库的一部分或可执行文件的主要部分。它有 name,可以指定 dependencies(依赖包内部的其他目标或外部依赖包的产品),path(相对于 Package.swift 的源代码目录),以及可选的 resourcesswiftSettings 等。
      • .testTarget: 一个用于编写单元测试和集成测试的特殊目标。它通常依赖于要测试的源代码目标,并使用 XCTest 框架。
        目标之间的依赖使用 .target(name:).product(name: package:) 指定。.product 用于引用外部依赖包暴露的产品。

6. 在 Xcode 中开发 Swift 包

将 Swift 包添加到 Xcode 项目后,你可以在 Xcode 中直接打开和编辑该包的代码。在项目导航器的 Package Dependencies 部分,展开你添加的包,你可以看到它的源文件和测试文件。双击文件即可在 Xcode 中编辑。

如果你是创建自己的包,你可以直接在 Xcode 中打开该包目录下的 Package.swift 文件,Xcode 会将整个包作为一个项目来管理,你可以在其中编写代码、运行测试。

7. 构建、测试和运行

  • 构建:
    • Xcode: 构建包含 SPM 依赖的项目或直接构建 SPM 包时,Xcode 会自动处理依赖的下载、构建和链接。只需像往常一样选择目标并点击构建按钮 (Cmd + B)。
    • 命令行: 在包的根目录下(包含 Package.swift),运行 swift build 命令来构建包。如果包是可执行类型,构建成功后,可执行文件通常位于 .build/debug/.build/release/ 目录下。
  • 测试:
    • Xcode: 打开 Test Navigator (Cmd + 6),你可以看到包中的测试目标和具体的测试用例。点击运行按钮即可执行测试。
    • 命令行: 在包的根目录下,运行 swift test 命令来运行包中的所有测试。
  • 运行 (仅限可执行包):
    • Xcode: 选择可执行目标并运行 (Cmd + R)。
    • 命令行: 在包的根目录下,运行 swift run [target-name] 命令来构建并运行指定的可执行目标。如果包只有一个可执行目标,[target-name] 可以省略。

8. 资源文件处理 (Resources)

SPM 支持在包中包含资源文件(如图片、JSON、本地化字符串等)。在目标的定义中,使用 resources 参数指定资源:

swift
.target(
name: "MyAwesomeLibrary",
dependencies: [],
path: "Sources/MyAwesomeLibrary",
resources: [
// 将 Resources 目录下的所有文件复制到目标 bundle 中
.process("Resources"),
// 或者只复制特定文件
// .copy("Data/config.json")
]
)

  • .process: 这是推荐的方式。SPM 会根据平台对资源进行优化处理(例如,为 iOS 上的图片生成不同分辨率)。处理后的资源会放在一个由 SPM 管理的 bundle 中。
  • .copy: 直接将文件或目录复制到目标 bundle 中,不做任何处理。适用于不需要优化的文件类型。

在代码中访问这些资源需要找到 SPM 生成的 bundle。通常,你可以通过 Bundle.module 访问当前包的资源 bundle:

swift
// 在 MyAwesomeLibrary.swift 中访问资源
let bundle = Bundle.module
if let url = bundle.url(forResource: "config", withExtension: "json") {
// 读取资源文件
let data = try Data(contentsOf: url)
// ...
}

注意: Bundle.module 是一个 SPM 提供的便利属性,仅在将你的包作为依赖添加到应用项目时可用。如果你直接构建和运行你的包(例如一个命令行工具),或者在测试目标中访问资源,访问 bundle 的方式可能有所不同,需要根据具体情况调整。对于测试,通常可以直接访问测试源文件旁边的资源文件路径。

9. 版本锁定 (Package.resolved)

Package.resolved 文件记录了每个直接和间接依赖在最后一次解析/更新时被锁定的精确版本、分支或提交哈希。这是实现构建确定性的关键。

  • 重要性: 确保你的项目在任何时间、任何机器上都能使用完全相同的依赖版本进行构建。这避免了由于依赖版本变动导致的不可预测的行为或构建失败。
  • 版本控制: 务必将 Package.resolved 文件提交到你的版本控制系统中 (Git)。当你克隆一个项目时,SPM 会读取 Package.resolved 文件来获取精确的依赖版本,而不是仅仅依赖 Package.swift 中的版本规则。
  • 更新: 当你运行 swift package update 或通过 Xcode GUI 更新包时,SPM 会重新解析依赖并更新 Package.resolved 文件。

10. 本地依赖和开发流程

在开发或调试一个包时,你可能需要让另一个项目或包依赖你本地正在修改的版本,而不是远程仓库的版本。这时可以使用本地依赖:

swift
dependencies: [
// 依赖本地路径的包
.package(path: "../MyAwesomeLibrary"),
// 其他远程依赖...
]

Package.swift 中使用 path: 参数指定本地包的相对或绝对路径。这样,SPM 会直接使用该路径下的代码,而不是从远程仓库下载。当你修改本地包的代码时,依赖它的项目会立即看到这些改动,无需提交或推送。

当你准备发布或共享你的包时,你需要将本地依赖改回远程仓库的 URL 和版本规则。

另一种本地开发方式是使用 swift package edit <PackageName> 命令。这个命令会将指定的远程依赖包克隆到你当前包的 Dependencies 目录下,并修改 .Package.resolved 文件指向本地路径。你可以直接在 Dependencies 目录下修改该依赖的代码。当你完成修改后,可以使用 swift package unedit <PackageName> 恢复到从远程仓库拉取。这个方法也很方便用于调试或向依赖库贡献代码。

11. 常见问题与故障排除

  • 依赖解析失败: 检查 Package.swift 文件中的依赖 URL 是否正确,版本规则是否与仓库中存在的标签/分支匹配。可能是网络问题导致无法访问仓库。检查依赖包是否有传递性依赖冲突。
  • 构建失败: 可能是代码错误,或者依赖未正确链接到目标。在 Xcode 中检查目标的 “Frameworks, Libraries, and Embedded Content” 设置,确保 SPM 管理的产品已被正确列出。清理构建缓存 (swift package clean 或 Xcode 的 Clean Build Folder)。
  • Xcode 无法识别模块: 确保你在代码中使用了正确的 import PackageName。检查包产品是否已正确添加到你的目标中。重启 Xcode 有时也能解决这类问题。
  • Package.resolved 冲突: 在团队协作中,如果多人同时修改依赖,可能导致 Package.resolved 文件冲突。解决冲突时,需要仔细查看哪些依赖被更改,并合并期望的版本。通常以更新的版本为准,但要小心潜在的不兼容性。

12. 局限性

虽然 SPM 发展迅速并日趋成熟,但仍然存在一些需要注意的地方:

  • 生态系统: 虽然 SPM 社区日益壮大,但一些老旧的库可能仍然只支持 CocoaPods 或 Carthage。不过越来越多的新库和活跃维护的库都已支持 SPM。
  • 二进制依赖: SPM 对预编译的二进制框架 (.framework.xcframework) 的支持相对较新(需要 Swift 5.3+ 和 Xcode 12+ 支持 XCFrameworks)。虽然现在已经可用,但在某些复杂场景下可能不如基于源码的依赖灵活。
  • 资源处理: 尽管有了 resources 参数,但在某些复杂的跨平台或混合语言项目中,资源管理仍可能需要额外配置。

13. 总结

Swift Package Manager 已经成为 Swift 开发中管理依赖和组织代码的标准方式。它深度集成于 Swift 工具链和 Xcode,提供了简单、高效、跨平台的包管理体验。

通过本文,你应该了解了:

  • SPM 的优势以及为什么应该使用它。
  • 如何在 Xcode 和命令行中将 Swift 包添加到你的项目。
  • 如何创建你自己的 Swift 包。
  • Package.swift 文件各个部分的含义和配置方法。
  • 如何在 Xcode 中开发和管理 Swift 包。
  • 构建、测试和运行包的基本命令。
  • 资源文件的处理方式。
  • Package.resolved 文件的作用和重要性。
  • 本地依赖和开发流程。
  • 一些常见的故障排除技巧。

现在,你已经具备了使用 Swift Package Manager 的基础知识。开始在你的项目中使用 SPM 吧,尝试添加一些常用的开源库,或者将你自己的通用代码打包成可复用的 Swift 包。随着实践的深入,你会越来越熟练地掌握这个强大的工具,让你的 Swift 开发工作更加高效和愉快!

如果你想深入了解更多高级特性,可以查阅官方的 Swift Package Manager 文档,它是最权威和详细的参考资料。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部