Last active
November 15, 2020 10:27
-
-
Save andyyhope/b2fbd9cbbc48a7d9d56ca3feb55bc1f5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: | |
//: UserDefaultable.swift | |
//: | |
//: Created by Andyy Hope on 18/08/2016. | |
//: Twitter: @andyyhope | |
//: Medium: Andyy Hope, https://medium.com/@AndyyHope | |
import Foundation | |
// MARK: - Key Namespaceable | |
protocol KeyNamespaceable { } | |
extension KeyNamespaceable { | |
private static func namespace(_ key: String) -> String { | |
return "\(Self.self).\(key)" | |
} | |
static func namespace<T: RawRepresentable>(_ key: T) -> String where T.RawValue == String { | |
return namespace(key.rawValue) | |
} | |
} | |
// MARK: - Bool Defaults | |
protocol BoolUserDefaultable : KeyNamespaceable { | |
associatedtype BoolDefaultKey : RawRepresentable | |
} | |
extension BoolUserDefaultable where BoolDefaultKey.RawValue == String { | |
// Set | |
static func set(_ bool: Bool, forKey key: BoolDefaultKey) { | |
let key = namespace(key) | |
UserDefaults.standard.set(bool, forKey: key) | |
} | |
// Get | |
static func bool(forKey key: BoolDefaultKey) -> Bool { | |
let key = namespace(key) | |
return UserDefaults.standard.bool(forKey: key) | |
} | |
} | |
// MARK: - Float Defaults | |
protocol FloatUserDefaultable : KeyNamespaceable { | |
associatedtype FloatDefaultKey : RawRepresentable | |
} | |
extension FloatUserDefaultable where FloatDefaultKey.RawValue == String { | |
// Set | |
static func set(_ float: Float, forKey key: FloatDefaultKey) { | |
let key = namespace(key) | |
UserDefaults.standard.set(float, forKey: key) | |
} | |
// Get | |
static func float(forKey key: FloatDefaultKey) -> Float { | |
let key = namespace(key) | |
return UserDefaults.standard.float(forKey: key) | |
} | |
} | |
// MARK: - Integer Defaults | |
protocol IntegerUserDefaultable : KeyNamespaceable { | |
associatedtype IntegerDefaultKey : RawRepresentable | |
} | |
extension IntegerUserDefaultable where IntegerDefaultKey.RawValue == String { | |
// Set | |
static func set(_ integer: Int, forKey key: IntegerDefaultKey) { | |
let key = namespace(key) | |
UserDefaults.standard.set(integer, forKey: key) | |
} | |
// Get | |
static func integer(forKey key: IntegerDefaultKey) -> Int { | |
let key = namespace(key) | |
return UserDefaults.standard.integer(forKey: key) | |
} | |
} | |
// MARK: - Object Defaults | |
protocol ObjectUserDefaultable : KeyNamespaceable { | |
associatedtype ObjectDefaultKey : RawRepresentable | |
} | |
extension ObjectUserDefaultable where ObjectDefaultKey.RawValue == String { | |
// Set | |
static func set(_ object: AnyObject, forKey key: ObjectDefaultKey) { | |
let key = namespace(key) | |
UserDefaults.standard.set(object, forKey: key) | |
} | |
// Get | |
static func object(forKey key: ObjectDefaultKey) -> Any? { | |
let key = namespace(key) | |
return UserDefaults.standard.object(forKey: key) | |
} | |
} | |
// MARK: - Double Defaults | |
protocol DoubleUserDefaultable : KeyNamespaceable { | |
associatedtype DoubleDefaultKey : RawRepresentable | |
} | |
extension DoubleUserDefaultable where DoubleDefaultKey.RawValue == String { | |
// Set | |
static func set(_ double: Double, forKey key: DoubleDefaultKey) { | |
let key = namespace(key) | |
UserDefaults.standard.set(double, forKey: key) | |
} | |
// Get | |
static func double(forKey key: DoubleDefaultKey) -> Double { | |
let key = namespace(key) | |
return UserDefaults.standard.double(forKey: key) | |
} | |
} | |
// MARK: - URL Defaults | |
protocol URLUserDefaultable : KeyNamespaceable { | |
associatedtype URLDefaultKey : RawRepresentable | |
} | |
extension URLUserDefaultable where URLDefaultKey.RawValue == String { | |
// Set | |
static func set(_ url: URL, forKey key: URLDefaultKey) { | |
let key = namespace(key) | |
UserDefaults.standard.set(url, forKey: key) | |
} | |
// Get | |
static func url(forKey key: URLDefaultKey) -> URL? { | |
let key = namespace(key) | |
return UserDefaults.standard.url(forKey: key) | |
} | |
} | |
// MARK: - Use | |
// Preparation | |
extension UserDefaults { | |
struct Account : BoolUserDefaultable { | |
private init() { } | |
enum BoolDefaultKey : String { | |
case isUserLoggedIn | |
} | |
} | |
} | |
// Set | |
UserDefaults.Account.set(true, forKey: .isUserLoggedIn) | |
// Get | |
let isUserLoggedIn = UserDefaults.Account.bool(forKey: .isUserLoggedIn) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is really cool!
@andyyhope how do you get the keypath to use in UserDefaults.standard.observe?