Skip to content

stefanprojchev/ForgeStorage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ForgeStorage

Type-safe key-value, file, and Keychain storage for iOS.

Swift 6.3+ iOS 18+ macOS 15+ License Release

πŸ“– Full documentation β†’


ForgeStorage covers every persistence need in a typical iOS app through three focused libraries. Each library exposes a protocol, a production implementation, and an in-memory test double β€” so you can swap the storage layer out for tests without touching your production code.

Libraries

Library Protocol Production Test double Use for
ForgeKVStore KVStoring UserDefaultsKVStore, DiskKVStore InMemoryKVStore Settings, flags, small data
ForgeFileStore FileStoring DiskFileStore InMemoryFileStore Images, videos, documents, cache
ForgeCrypt CryptStoring CryptStore (Keychain) InMemoryCrypt Tokens, passwords, secrets
ForgeStorage umbrella β€” β€” Re-exports all three

Features

  • Type-safe keys β€” KVKey<T> and CryptKey<T> give compile-time safety for reads and writes
  • Protocol-oriented β€” every store is behind a protocol, making mocking trivial
  • Reactive KV β€” wrap any KVStoring with KVReactiveStore for AsyncStream-based observation
  • Configurable Keychain accessibility β€” .whenUnlocked, .afterFirstUnlock, .whenUnlockedThisDeviceOnly, etc.
  • JSON convenience β€” built-in Codable round-trips for file and KV stores
  • Zero Combine dependency β€” pure Swift Concurrency

Requirements

  • iOS 18+
  • macOS 15+
  • Swift 6.3+ (Xcode 26 or later)

Installation

Xcode

  1. File β†’ Add Package Dependencies…
  2. Paste https://github.com/stefanprojchev/ForgeStorage.git
  3. Set rule to Up to Next Major from 1.0.0

Package.swift

dependencies: [
    .package(url: "https://github.com/stefanprojchev/ForgeStorage.git", from: "1.0.0")
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [
            "ForgeStorage",     // all three libraries
            // β€” or pick individually β€”
            // "ForgeKVStore",
            // "ForgeFileStore",
            // "ForgeCrypt",
        ]
    )
]

Quick Start

Key-value storage

import ForgeKVStore

// Define typed keys
enum AppKeys {
    static let onboarded = KVKey<Bool>("app.onboarded")
    static let launchCount = KVKey<Int>("app.launchCount")
}

let store: KVStoring = UserDefaultsKVStore()

try store.set(AppKeys.onboarded, value: true)
let done = store.get(AppKeys.onboarded) ?? false

Reactive observation

import ForgeKVStore

let reactive = KVReactiveStore(UserDefaultsKVStore())

for await value in reactive.stream(AppKeys.launchCount) {
    print("Launch count:", value ?? 0)
}

File storage

import ForgeFileStore

let store = DiskFileStore(directory: .caches, namespace: "avatars")

try await store.save(imageData, to: "user_42.jpg")
let data = try await store.load("user_42.jpg")

// JSON convenience
try await store.saveJSON(user, to: "user.json")
let loaded: User = try await store.loadJSON("user.json")

Keychain

import ForgeCrypt

enum AuthKeys {
    static let accessToken = CryptKey<String>(
        key: "auth.accessToken",
        accessibility: .afterFirstUnlock
    )
}

let keychain: CryptStoring = CryptStore(service: "com.yourapp")

try keychain.set("eyJhbG...", for: AuthKeys.accessToken)
let token: String? = try keychain.get(AuthKeys.accessToken)
try keychain.delete(AuthKeys.accessToken)

Testing

Every store has an in-memory test double you can use instead of the production implementation:

import Testing
import ForgeKVStore

@Test
func incrementsLaunchCount() throws {
    let store: KVStoring = InMemoryKVStore()

    let initial = store.get(AppKeys.launchCount) ?? 0
    try store.set(AppKeys.launchCount, value: initial + 1)

    #expect(store.get(AppKeys.launchCount) == 1)
}

Documentation

The Forge Family

ForgeStorage is part of the Forge family of Swift packages for iOS.

Package Description
ForgeCore Thread-safe primitives for iOS Swift packages.
ForgeInject Dependency injection with constructor and property wrapper support.
ForgeObservers Reactive system observers β€” connectivity, lifecycle, keyboard, and more.
ForgeStorage Type-safe key-value, file, and Keychain storage.
ForgeOrchestrator Orchestrate app flows β€” startup gates, data pipelines, and continuous monitors.
ForgePush Push notification management β€” permissions, tokens, and routing.
ForgeLocation Location triggers β€” geofencing, significant changes, and visits.
ForgeBackgroundTasks Background task scheduling and dispatch.

License

ForgeStorage is released under the MIT License. See LICENSE.

About

Type-safe key-value, file, and Keychain storage for iOS.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages