Typo

1.0.1

(Yet another) Type safe UserDefaults wrapper
chernousov-m/Typo

What's New

2021-10-30T10:17:03Z

Typo

Type safe UserDefaults wrapper

Usage

Define your namespaces

import Typo

enum Global: NamespaceTag {}
enum Nested: NamespaceTag {}

Define properties (and nested namespaces)

extension Namespace where Tag == Global {
  var nestedNS: Namespace<Nested> { .init() }
  var intProperty: Property<Int> { .init(default: .zero) }
}

extension Namespace where Tag == Nested {
  var stringProperty: Property<String> { .init(default: "") }
}

Create StorageProxy

let proxy = StorageProxy(
  namespaceTag: Global.self,
  storage: UserDefaults.standard
)

Use the proxy to access your properties

let int = proxy.intProperty
let string = proxy.nestedNS.stringProperty

Using custom types

To store your types, implement Value protocol

public protocol Value: Codable {
    static var typeIdentifier: String { get }
}

typeIdentifier is used to preserve type information when encoding values

Customization

You can customize keys using StorageProxy initializer

StorageProxy(
  namespaceTag: ,
  storage: ,
  keyPrefix: ,
  keyTransformation:
)

Included, but not limited to UserDefauls

If you want Typo to use other types of storages, just implement Storage protocol

public protocol Storage: AnyObject {
    subscript(_ key: String) -> Data? { get set }
}

This way you can make any type of key-value storage to be compatible with typo (plain dictionary, NSCache, KeyChain, CoreData, etc)

Migrations

Your app data and it's structure may (and will) evolve over time. Typo provides mechanism to add migrations to properties

extension Namespace where Tag == Global {
  var intProperty: Property<Int> {
    Property(default: 0)
      .migration(
        Migration(initialType: Double.self)
          .migrate {
            Int(exactly: $0) ?? 0
          }
      )
  }
}

Getting keys

In case you need to get keys for your properties (e.g. your storage has some kind of observing), you can call the StorageProxy to get KeyKeeper object and use it the same way you use proxy to get keys for the properties insted of values

let proxy = StorageProxy(
  namespaceTag: Global.self,
  storage: UserDefaults.standard
)

print(proxy().nestedNS.stringProperty) // "nestedNS/stringProperty"

Contribute

Feel free to open an issue or pull-request

Description

  • Swift Tools 5.3.0
View More Packages from this Author

Dependencies

  • None
Last updated: Wed Nov 09 2022 15:39:36 GMT-1000 (Hawaii-Aleutian Standard Time)