Skip to content

maximkrouk/Storage

Repository files navigation

Storage

Every type of storage:

  • Has the same interface.
  • Extendable.
  • Thread safe.

Interface:

Any storage provided via managers is accessible as key-value pairs. You may use strings, but you'll be getting warnings, because I deprecated this approach. Natively the framework advices you to use string based enums.

In exaples I'll be using this:

enum Auth: String {
    case username // .rawValue == "username"
    case isAdmin  // .rawValue == "isAdmin"
}

Avalible Managers:

  • Keychain

    Shortcut: KC

  • UserDefaults

    Shortcut: UD

  • Cache [temporary / persistent]

    Shortcut: CH

You can easily extend Avalible managers with your own by writinfg an implementation and subscribing your managers to a StorageManagerProtocol

You should access any storage via providers. You may use them as static or singleton's properties.

  • [Manager].[Provider]

Out-of-the-box Providers:

  • .data
  • .bool
  • .string

Providers allow you to access storage:

  • Via subscripts:
    • provider[key]
  • Via methods:
    • provider.get(for: key)
    • provider.set(value, for: key)
  • Via deprecated subscripts and methods:
    • provider[stringKey]
    • provider.get(forKey: stringKey)
    • provider.set(value, forKey: stringKey)

For convenience it would be nice to extend framework's Storage.Provider with your custom adapter subscripts:

extension Storage.Provider {
    subscript(key: Auth) -> Value? {    // Value is a Provider's assosiated type.
        get { get(for: key) }           // Just pass key to build-in getter,
        set { set(newValue, for: key) } // or key-value to build in setter.
    }
}

This will allow you to access storage not just like this:

  • Storage.[Manager].[Provider][Auth.username]

but also like this:

  • Storage.[Manager].[Provider][.username]

Keychain as an example:

  • Storage.Keychain.data.set(nil, forKey: "deletedItem")
  • Storage.Keychain.data.get(forKey: "deletedItem") // nil
  • Storage.Keychain.data["StringKeys"] = "Sucks c:".data(using: .utf8)
  • Storage.Keychain.default.string[.username] = "Root"
  • Storage.Keychain.default.bool[.isAdmin] = true
  • Storage.KC.bool[.isAdmin] // true