Skip to content

Instantly share code, notes, and snippets.

@d3signerd
Created September 11, 2019 14:25
Show Gist options
  • Save d3signerd/bd0fa632c18ec7a65e34c5134e4c018a to your computer and use it in GitHub Desktop.
Save d3signerd/bd0fa632c18ec7a65e34c5134e4c018a to your computer and use it in GitHub Desktop.
UserDefaults Wrapper with Generic Keys (swift)
//
// DefaultKey.swift
//
// Created by Kellen Styler on 9/9/19.
//
/// Default Key -Used by Defaults for keyed values
public struct DefaultKey<DefaultType> {
// MARK: Properties
let name: String
// MARK: Lifecycle
/// Init with name and initial value
///
/// - Parameters:
/// - name: String
/// - initialValue: Any
public init(_ name: String, initialValue: Any) {
self.name = name
// Register the initial value
Defaults.registerValue(initialValue, forKeyName: name)
}
}
// MARK: - Equatable
extension DefaultKey: Equatable {
public static func ==<T>(lhs: DefaultKey<T>, rhs: DefaultKey<T>) -> Bool {
return lhs.name == rhs.name
}
}
//
// Defaults.swift
//
// Created by Kellen Styler on 9/10/19.
//
/// Defaults -UserDefaults wrapper
final public class Defaults {
// MARK: Public
/// Get Value for key
///
/// - Parameter key: DefaultKey<DefaultType>
/// - Returns: DefaultType
public static func getValue<DefaultType>(for key: DefaultKey<DefaultType>) -> DefaultType {
synchronize()
return standard.value(forKey: key.name) as! DefaultType
}
/// Register Value for key name
/// - NOTE: `forKeyName` is a string value to allow registration during init
/// of `DefaultKey`s.
///
/// - Parameters:
/// - value: DefaultType
/// - name: String
public static func registerValue<DefaultType>(_ value: DefaultType, forKeyName name: String) {
standard.register(defaults: [name: value])
synchronize()
}
/// Set Value for key
///
/// - Parameters:
/// - value: DefaultType?
/// - key: DefaultKey<DefaultType>
public static func setValue<DefaultType>(_ value: DefaultType?, for key: DefaultKey<DefaultType>) {
// Set
if let value = value {
standard.setValue(value, forKey: key.name)
synchronize()
}
// Clear if nil
else {
clearValue(for: key)
}
}
}
// MARK: - Private Helpers
fileprivate extension Defaults {
// MARK: Static Properties
static var standard = UserDefaults.standard
// MARK: Static Methods
/// Synchronize
static func synchronize() {
standard.synchronize()
}
}
// MARK: - Private Extension
fileprivate extension Defaults {
/// Clear Value for key
///
/// - Parameter key: DefaultKey<DefaultType>
static func clearValue<DefaultType>(for key: DefaultKey<DefaultType>) {
standard.removeObject(forKey: key.name)
synchronize()
}
}
// MARK: - Your DefaultKey Extention
public extension DefaultKey {
static var yourKeyName: DefaultKey<Date> { return DefaultKey<Date>("your_key_name", initialValue: Date.distantPast) }
}
// Just simply create your keys like shown above.
// Then, use them like so:
Defaults.setValue(Date.distantPast, for: .yourKeyName)
let yourKeyValue = Defaults.getValue(for: .yourKeyName)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment