niksativa/storagekit
**StorageKit** is a Swift library that provides a unified, type-safe interface for storing and retrieving data across multiple backends. It supports declarative property wrappers and integrates with Combine for reactive state updates. Ideal for modern app architectures requiring
Key Features
- Type-safe read/write access to stored values
- Reactive integration with Combine for observing value changes
- Support for multiple storage backends:
- UserDefaults - File system - Keychain - In-memory
- Property wrappers for declarative usage
- Support for composable storage layers
- Built-in expiration handling for time-sensitive values
Installation
Swift Package Manager
Add the following to your Package.swift file:
dependencies: [
.package(url: "https://github.com/NikSativa/StorageKit.git", from: "1.0.0")
]Usage
Property Wrappers
@Defaults
Property wrapper that provides type-safe access to values persisted in UserDefaults. Supports Codable types:
import StorageKit
struct User: Codable {
let name: String
let email: String
let age: Int
}
final class UserViewModel {
@Defaults("user")
var user: User? {
didSet {
print("User updated: \(user)")
}
}
}@Expirable
Property wrapper that adds expiration to stored values:
@Expirable(lifetime: .oneHour) var token: String?Storage Types
UserDefaultsStorage
Persistent storage using UserDefaults:
let storage = UserDefaultsStorage<Int?>(key: "MyKey")
storage.value = 1FileStorage
Persistent storage using the file system. Supports customizable file paths:
let storage = FileStorage<Int>(fileName: "TestFile.txt")
storage.value = 1KeychainStorage
Secure storage using the Keychain:
let storage = KeychainStorage(
key: "MyKey",
configuration: .init(service: Bundle.main.bundleIdentifier ?? "MyService")
)
storage.value = auth.tokenInMemoryStorage
Transient storage using in-memory values:
let storage = InMemoryStorage<Int>(value: 1)
storage.value = 1Storage Composition
Combine multiple storage layers for advanced scenarios:
// Combine two storages
let combined = inMemoryStorage.combine(userDefaultsStorage)
// Combine multiple storages (iOS 16+)
let combined = zip(storages: [
InMemoryStorage<Int?>(value: 1),
UserDefaultsStorage(key: "MyKey")
])
// For non-nil literal types provide explicit defaultValue
let combinedInt = zip(
storages: [
InMemoryStorage<Int>(value: 1),
UserDefaultsStorage<Int>(key: "MyKey", defaultValue: 0)
],
defaultValue: 0
)Reactive Updates
All storage types provide Combine publishers for observing value changes:
let storage = UserDefaultsStorage<String>(key: "MyKey")
let cancellable = storage.sink { value in
print("Value updated: \(value)")
}Requirements
- iOS 13.0+ / macOS 11.0+ / tvOS 13.0+ / watchOS 6.0+ / visionOS 1.0+
- Swift 5.10+
- Xcode 15.0+
License
StorageKit is available under the MIT license. See the LICENSE file for more info.
Package Metadata
Repository: niksativa/storagekit
Default branch: main
README: README.md