DataThespian 是一个线程安全的 SwiftData 实现,它利用 ModelActor 的强大功能来提供优化的、类型安全的数据库接口。它为常见的数据库操作提供了一个简洁的 API,同时保持并发安全性并防止常见的 SwiftData 缺陷。
主要特性
Apple 平台
Linux
要使用 SPM 将 DataThespian 集成到您的应用程序中,请在您的 Package.swift 文件中指定它
let package = Package(
...
dependencies: [
.package(url: "https://github.com/brightdigit/DataThespian.git", from: "1.0.0")
],
targets: [
.target(
name: "YourApps",
dependencies: [
.product(name: "DataThespian", package: "DataThespian"), ...
]),
...
]
)
在使用 SwiftData 时,在您的整个应用程序中使用单个 ModelContext
至关重要。 有两种创建数据库的方法
// Create a database using the built-in ModelActorDatabase
let database = ModelActorDatabase(modelContainer: container)
您还可以通过实现 Database
协议来创建您自己的数据库类型
@ModelActor
actor CustomDatabase: Database {
}
为了避免每次 SwiftUI 重绘视图时创建多个 ModelContext 的问题,请使用 SharedDatabase
来确保单个共享上下文
public struct SharedDatabase {
public static let shared: SharedDatabase = .init()
public let schemas: [any PersistentModel.Type]
public let modelContainer: ModelContainer
public let database: any Database
private init(
schemas: [any PersistentModel.Type] = .all,
modelContainer: ModelContainer? = nil,
database: (any Database)? = nil
) {
self.schemas = schemas
let modelContainer = modelContainer ?? .forTypes(schemas)
self.modelContainer = modelContainer
self.database = database ?? ModelActorDatabase(modelContainer: modelContainer)
}
}
然后在您的 SwiftUI 应用程序中设置数据库
var body: some Scene {
WindowGroup {
RootView()
}
.database(SharedDatabase.shared.database)
/* If you need @Query support
.modelContainer(SharedDatabase.shared.modelContainer)
*/
}
使用 environment 在您的视图中访问数据库
@Environment(\.database) private var database
DataThespian 提供一种类型安全的方式来查询您的数据
// Fetch a single item
let item = try await database.get(for: .predicate(#Predicate<Item> {
$0.name == "Test"
}))
// Fetch multiple items with sorting
let items = await database.fetch(for: .descriptor(
predicate: #Predicate<Item> { $0.isActive },
sortBy: [SortDescriptor(\Item.timestamp, order: .reverse)]
))
// Insert new item
let timestamp = Date()
let newItem = await database.insert {
Item(name: "Test", timestamp: timestamp)
}
// Save changes
try await database.save()
// Re-query after save using a unique field
let savedItem = try await database.getOptional(for: .predicate(#Predicate<Item> {
$0.timestamp == timestamp
}))
要了解更多信息,请查看完整的文档。
此代码在 MIT 许可证下分发。 有关更多信息,请参见 LICENSE 文件。