Swift Package Manager(简称SPM)是苹果官方推出的Swift语言依赖管理工具,与Swift语言深度融合,支持Swift跨平台开发(涵盖iOS、macOS、Linux等系统),能够自动化完成包的依赖下载、编译、链接及管理流程。
Package(包)
包含Swift源代码及Package.swift清单文件的目录集合。
Products(产物)
包对外提供的成果物,主要包括库(Library)和可执行程序(Executable),其中库是最常用的类型,作为可重用组件供其他代码导入使用。
Target(目标)
构建过程中的基本单元,由一组源代码文件组成,可依赖于其他目标(如库、可执行程序等)。
Dependencies(依赖)
当前包所需要的其他外部包,SPM会自动完成这些依赖项的获取与构建。
Tools version(工具版本)
指定构建该包所需的最低Swift工具链版本。
官方原生支持:由苹果开发,与Swift语言及Xcode深度集成,无需额外安装。
跨平台兼容:在所有支持Swift的平台(Linux、macOS、Windows)均可正常工作。
声明式依赖管理:通过Package.swift文件声明依赖关系,结构清晰、易于理解。
自动化处理流程:自动完成依赖的下载、编译及版本冲突解决(基于语义化版本控制)。
Xcode无缝协作:可在Xcode中直接编辑和管理Swift包,添加依赖时只需输入包的URL或直接导入,操作便捷。
常用的SPM命令如下:
swift package init --type library # 初始化库类型包
swift build # 构建包
swift test # 执行测试
swift run <executable-target> # 运行可执行目标
swift package resolve # 解析依赖
swift package update # 更新依赖
通过命令行可快速创建不同类型的包,具体命令如下:
# 创建库类型包
swift package init --name MyLibrary --type library
# 创建可执行类型包
swift package init --name MyExecutable --type executable
执行上述命令后,会在当前目录生成标准的包结构(以库包为例):
MyLibrary/
├── Sources/
│ └── MyLibrary/
│ └── MyLibrary.swift
├── Tests/
│ └── MyLibraryTests/
│ └── MyLibraryTests.swift
└── Package.swift
目录结构示意图:

Package.swift清单文件的基本内容如下:
// swift-tools-version: 6.0
// swift-tools-version指定构建该包所需的最低Swift版本
import PackageDescription
let package = Package(
name: "MyLibrary",
platforms: [.iOS(.v18), .macOS(.v15)],// 指定支持的平台及最低版本
products: [
.library(name: "MyLibrary", targets: ["MyLibrary"])// 定义编译后对外提供的产物
],
dependencies: [// 声明依赖的外部包
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.8.0")
],
targets: [// 定义包的构建目标信息
.target(
name: "MyLibrary",
dependencies: ["Alamofire"],
resources: [.process("Resources")]
),
.testTarget(
name: "MyLibraryTests",
dependencies: ["MyLibrary"]
)
]
)
Sources目录是存放实现代码的主要位置,以MyLibrary.swift为例,它通常作为程序的核心实现文件,包含主要功能代码。
# 编译包
swift build
# 运行测试用例
swift test
# 运行可执行包
swift run
打开Xcode项目。
选择菜单栏的File > Add Packages...,如图所示:

在弹出窗口中,可选择Add Local添加本地包(如图所示):

也可直接输入包的URL添加远程包(如图所示):

选择完成后点击Add Package,Xcode会自动解析并下载该包及其所有依赖项。
导入的依赖包会显示在项目导航器的Package Dependencies部分,之后即可在代码中通过import语句使用。
若在Xcode的Package Dependencies中无法直接删除已导入的包,可通过以下方式处理:
进入项目的.xcodeproj包内,编辑project.pbxproj文件,删除与该包相关的配置内容,保存后即可在项目中移除该包。示意图如下:

编译后的Swift包会以库或资源的形式嵌入到应用中:
静态库(static library):编译后其目标代码会被链接到主可执行文件中,应用内不会出现单独的库文件。
动态框架(dynamic framework/XCFramework):通常以框架形式存放在应用包的Frameworks目录下,路径类似Payload/MyApp.app/Frameworks/<Name>.framework或<Name>.xcframework。
由于编译后的目标文件包含汇编指令和符号表等信息,通过反编译工具可将其解析为类C伪代码。对于仅交付静态库和目标文件的场景,为防止程序被逆向破解,对这些文件的保护至关重要。
Virbox Protector工具在静态库和动态库保护方面有成熟方案,可实现函数级和整体保护。具体方案可参考官网文档:
静态库保护:静态库和目标文件保护最佳实践
动态库保护:Native程序保护最佳实践