https://github.com/juyan/swift-filestore
Lightweight key-value store with Structured Concurrency API
https://github.com/juyan/swift-filestore
database ios key-value-store macos swift
Last synced: about 1 year ago
JSON representation
Lightweight key-value store with Structured Concurrency API
- Host: GitHub
- URL: https://github.com/juyan/swift-filestore
- Owner: juyan
- License: mit
- Created: 2023-05-24T06:23:12.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2025-01-29T22:11:30.000Z (over 1 year ago)
- Last Synced: 2025-04-09T09:01:47.263Z (about 1 year ago)
- Topics: database, ios, key-value-store, macos, swift
- Language: Swift
- Homepage:
- Size: 35.2 KB
- Stars: 6
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# swift-filestore
Lightweight key-value store with Structured Concurrency API.





## Why swift-filestore?
If your app is built with Swift Concurrency and is in need for a lightweight key-value storage solution, `swift-filestore` should be a good fit.
It is a key-value persistence solution which provides CRUD operation and change stream APIs under Swift's Structured Concurrency(`async/await`, `AsyncSequence`).
Under the hood it simply serializes each object into a separate file, no databases or caches solutions are involved. This keeps your app lean and stable.
## Quick Start
Obtain an instance by calling `FileObjectStore.create()`. The method simply create a root directory under app's `Application Support` directory.
In rare cases where it fails to create the directory, you can choose to fallback to a in-memory implementation of `ObjectStore`, or can handle it in your own way.
```swift
func createWithFallback() -> ObjectStore {
do {
return try FileObjectStore.create()
} catch {
return MemoryObjectStore()
}
}
```
`swift-filestore` does not require developers to create new struct/classes for your data model. For example, to use JSON serialization, just have your existing model conform to `JSONDataRepresentable`.
```swift
struct MyModel: Codable, JSONDataRepresentable {
let id: String
let value: String
}
let model = MyModel()
try await objectStore.write(key: model.id, namespace: "MyModels", object: model)
```
## Object Change Stream
`swift-filestore` offers an object change subscription API via Swift Concurrency.
```swift
for try await model in await objectStore.observe(key: id, namespace: "MyModels", objectType: MyModel.self) {
// process the newly emitted model object
}
```
## Custom serialization/deserialization
If you are looking for non-json serializations, you can define your custom serialization/deserialization protocol as below:
```swift
protocol BinaryDataRepresentable: DataRepresentable {}
extension BinaryDataRepresentable {
public func serialize() throws -> Data {
// your custom serialization goes here...
}
public static func from(data: Data) throws -> Self {
// your custom deseriazation goes here...
}
}
struct MyModel: BinaryDataRepresentable {
let id: String
let value: String
}
```
## PersistenceLog
`swift-filestore` offers an immutable logging component named `PersistenceLog`. It allows developer to store records on the disk and flush them at the right time. It can be used as an alternative to in-memory logging, which may risk data loss because app can be terminated at any time by user or the system.
Below code demonstrates how to use `PersistenceLog` to store and send in-app analytic events:
```swift
//data model for the analytics log
struct AnalyticsEvent: Codable, JSONDataRepresentable {
let name: String
let metaData: String
}
//initialization
let log = try PersistenceLogImpl(name: "analytics-log")
//When new event is triggered
try await log.append(event1)
//When it's time to flush and sent to remote server
let events = try await log.flush()
try await networkClient.sendAnalytics(events)
```