Papyrus 通过提供简单的对象缓存层,使应用程序能够首先离线工作。
struct Car: Papyrus {
let id: String
let model: String
let manufacturer: String
}
let car = Car(id: "abc...", model: "Model S", manufacturer: "Tesla")
let store = PapyrusStore()
try await store.save(car)
在此示例中,我们使用 AsyncThrowingStream
来传递值。
一般概念是,首先我们产生缓存数据,执行 API 请求,产生新对象,最后合并新的缓存对象。
import AsyncAlgorithms
import Papyrus
struct CarProvider {
var all: () -> AsyncThrowingStream<[Car], Error>
}
extension CarProvider {
static func live(
apiClient: TeslaAPIClient = .live,
store: PapyrusStore = .live
) -> Self {
.init(
all: {
AsyncThrowingStream { continuation in
do {
var stores = store.objects(type: Car.self).execute()
continuation.yield(stores)
let request = FetchCarsRequest()
cars = try await apiClient.execute(request: request)
continuation.yield(cars)
try await store.merge(with: cars)
continuation.finish()
} catch {
continuation.finish(throwing: error)
}
}
.removeDuplicates()
.eraseToThrowingStream()
}
)
}
}
在 Xcode 中
Project
。Package Dependencies
。+
。https://github.com/reddavis/Papyrus
。Papyrus
添加到你的应用程序目标。任何符合 Papyrus
协议的内容都可以被存储。
Papyrus
协议只是以下三个协议的统称
Codable
Equatable
Identifiable,其中 ID: LosslessStringConvertible
struct Car: Papyrus {
let id: String
let model: String
let manufacturer: String
}
let car = Car(id: "abc...", model: "Model S", manufacturer: "Tesla")
let store = PapyrusStore()
try await store.save(car)
在处理 API 时,一个常见的用例是获取对象集合并将结果合并到你的本地集合中。
Papyrus 为此提供了一个函数
let carA = Car(id: "abc...", model: "Model S", manufacturer: "Tesla")
let carB = Car(id: "def...", model: "Model 3", manufacturer: "Tesla")
let carC = Car(id: "ghi...", model: "Model X", manufacturer: "Tesla")
let store = PapyrusStore()
try await store.save(objects: [carA, carB])
try await store.merge(with: [carA, carC])
store
.objects(type: Car.self)
.execute()
// #=> [carA, carC]
获取对象有两种形式
let store = PapyrusStore()
let tesla = store.object(id: "abc...", of: Manufacturer.self).execute()
let store = PapyrusStore()
let stream = store.object(id: "abc...", of: Manufacturer.self).stream()
do {
for try await object in stream {
...
}
} catch {
//.. Do something
}
Papryrus 使你能够获取、筛选和观察对象集合。
let manufacturers = self.store
.objects(type: Manufacturer.self)
.execute()
let manufacturers = await self.store
.objects(type: Manufacturer.self)
.filter { $0.name == "Tesla" }
.execute()
let manufacturers = await self.store
.objects(type: Manufacturer.self)
.sort { $0.name < $1.name }
.execute()
在 PapryrusStore.CollectionQuery
对象上调用 stream()
将返回一个 AsyncThrowingStream
,它将发出对象集合。除非另有说明,否则只要检测到更改,流将继续发出对象集合。
更改包括
let stream = self.store
.objects(type: Manufacturer.self)
.filter { $0.name == "Tesla" }
.sort { $0.name < $1.name }
.stream()
do {
for try await manufacturers in stream {
// ... Do something with [Manufacturer].
}
} catch {
//.. Do something
}
有几种删除对象的方法。
let store = PapyrusStore()
let tesla = store.object(id: "abc...", of: Manufacturer.self)
try store.delete(tesla)
let store = PapyrusStore()
try store.delete(id: "abc...", of: Manufacturer.self)
let store = PapyrusStore()
let tesla = store.object(id: "abc...", of: Manufacturer.self)
let ford = store.object(id: "xyz...", of: Manufacturer.self)
try store.delete(objects: [tesla, ford])