StorageKit is a reusable Swift Package that provides a clean, scalable, and production-ready storage abstraction for Apple platforms.
It supports:
UserDefaultsstorage withCodable- Keychain-backed secure storage
- Property wrappers for clean SwiftUI usage
- Key namespacing and versioned key migration
- Thread-safe access patterns and dependency injection
- iOS 15+
- macOS 12+
- Swift 6.2+
In Xcode:
- Go to File > Add Packages...
- Enter your repository URL for
StorageKit - Select the version/range and add the package
Or in Package.swift:
dependencies: [
.package(url: "https://github.com/Coderkube-App/StorageKit.git", from: "1.0.0")
],
targets: [
.target(
name: "YourApp",
dependencies: [
.product(name: "StorageKit", package: "StorageKit")
]
)
]StorageKit/
├── Sources/StorageKit/
│ ├── Core/
│ ├── UserDefaults/
│ ├── Keychain/
│ ├── Secure/
│ ├── Codable/
│ ├── PropertyWrappers/
│ ├── Extensions/
│ └── StorageKit.swift
├── Tests/StorageKitTests/
└── Package.swift
public protocol StorageProtocol {
func save<T: Codable>(_ value: T, for key: String)
func fetch<T: Codable>(_ type: T.Type, for key: String) -> T?
func delete(for key: String)
}StorageKit.shared.userDefaults.save("Vijay", for: "name")
let name: String? = StorageKit.shared.userDefaults.fetch(String.self, for: "name")let defaults = StorageKit.shared.userDefaults
defaults.save(true, for: "isLoggedIn")
defaults.save(42, for: "launchCount")
defaults.save("Vijay", for: "username")
let isLoggedIn = defaults.fetch(Bool.self, for: "isLoggedIn")
let launchCount = defaults.fetch(Int.self, for: "launchCount")
let username = defaults.fetch(String.self, for: "username")let keychain = StorageKit.shared.keychain
keychain.save("token_abc123", for: "authToken")
let token = keychain.fetch(String.self, for: "authToken")
keychain.delete(for: "authToken")let secure = StorageKit.shared.secure
secure.save("super_secret", for: "secretKey")
let value = secure.fetch(String.self, for: "secretKey")import SwiftUI
import StorageKit
struct ContentView: View {
@UserDefault(key: "username", defaultValue: "")
private var username: String
@SecureValue(key: "authToken")
private var token: String?
var body: some View {
VStack {
TextField("Username", text: $username)
Button("Save Token") { token = "new_token" }
Button("Clear Token") { token = nil }
}
.padding()
}
}Use StorageKey helpers to keep keys organized:
let namespaced = StorageKey.namespaced("profile", namespace: "com.myapp")
let versioned = StorageKey.versioned("authToken", version: 2)let secure = StorageKit.shared.secure
secure.migrate([
StorageMigration(
fromKey: StorageKey.versioned("authToken", version: 1),
toKey: StorageKey.versioned("authToken", version: 2)
)
])StorageError provides shared error types:
encodingFaileddecodingFailedkeychainError(status:)dataNotFound
Run tests:
swift testThis repository uses a GitHub Actions workflow to automatically create version tags and GitHub Releases after changes are merged into main.
Version bump rules:
fix:or other non-breaking commits -> patch bump (x.y.Z)feat:-> minor bump (x.Y.0)BREAKING CHANGEin the commit body or footer -> major bump (X.0.0)
The workflow runs from .github/workflows/automated-versioning.yml and generates release notes automatically for each new version.
Current tests cover:
- Codable save/fetch/delete
- Primitive type support (
Bool,Int,String) - Keychain operations with mock helper
- Secure storage key migration
- Protocol-driven architecture for flexibility
- Dependency injection support for testability
- Thread-safe implementation using synchronization queues and locks
- No force unwraps in library code paths
Add your preferred license here (MIT, Apache-2.0, etc.).