项目介绍:swift-dependencies
概述
swift-dependencies 是一个受到 SwiftUI 中“环境”启发的依赖管理库。它旨在帮助开发者更好地控制应用程序中需与外部系统交互的类型和函数。常见的依赖实例包括 API 客户端、UUID、Date 初始化器、文件访问、用户默认设置,甚至时钟和计时器等。
在应用开发中,依赖管理(或“依赖注入”)通常不被过多考虑,但不受控的依赖会导致代码库和开发周期中的许多问题。通过库,开发者可以更好地控制这些依赖,解决以下问题:
- 编写快速、确定性测试的难度。
- 无法在 SwiftUI 预览中良好运作的依赖。
- 过于臃肿的第三方库依赖往往导致较长的编译时间。
swift-dependencies 帮助开发者以更舒适的方式将依赖传播至整个应用,并在确保安全的情况下随时重写这些依赖,特别是在测试、SwiftUI 预览以及用户引导程序中。
快速入门
这个库允许开发者注册自己的依赖类型,并提供了可控的依赖,帮助开发者更轻松地管理任务、日期、UUID 等。示例如下:
@Observable
final class FeatureModel {
var items: [Item] = []
@ObservationIgnored
@Dependency(\.continuousClock) var clock // 可控的任务休眠方式
@ObservationIgnored
@Dependency(\.date.now) var now // 可控的当前日期获取方式
@ObservationIgnored
@Dependency(\.mainQueue) var mainQueue // 可控的主线程调度
@ObservationIgnored
@Dependency(\.uuid) var uuid // 可控的 UUID 创建
// ...
}
在定义了依赖后,开发者可以通过模型操作依赖,而不是直接使用 Date()
、UUID()
等:
@Observable
final class FeatureModel {
// ...
func addButtonTapped() async throws {
try await clock.sleep(for: .seconds(1)) // 🤚 不使用 'Task.sleep'
items.append(
Item(
id: uuid(), // 🤚 不使用 'UUID()'
name: "",
createdAt: now // 🤚 不使用 'Date()'
)
)
}
}
项目示例和安装
通过这个库,我们重构了苹果的 Scrumdinger 演示应用,使用了现代 SwiftUI 开发的最佳实践。这展示了如何使用这个库控制文件系统访问、计时器和语音识别 API 的依赖。
要在 Xcode 项目中加入 Dependencies,可以将其作为包引入项目:
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.0.0")
]
并在需要的目标中添加产品:
.product(name: "Dependencies", package: "swift-dependencies"),
社区与扩展
如果你希望讨论这个库或有使用问题,可以加入 Point-Free 社区。库也支持拓展,以下项目基于 Dependencies 开发:
- Dependencies Additions:提供更高层次的依赖管理。
- Dependencies Protocol Extras:使 swift-dependencies 在使用协议时更为强大。
许可证
swift-dependencies 在 MIT 许可证下发布。该库不仅提供了一种全面的依赖管理方式,还具备扩展性强,可以在众多项目中应用。它解决了开发过程中常见的依赖问题,使得应用的依赖管理更为灵活和高效。