36

アプリ設定の保存をシンプルに

Embed Size (px)

Citation preview

UserDefaults.standard.set("hoge", forKey: "UserName")

// Key let userName = UserDefaults.standard.string(forKey: "UserrName")

// fatal error: unexpectedly found nil while unwrapping an Optional value print(userName!)

// Int set UserDefaults.standard.set(100, forKey: “UserID")

// String set UserDefaults.standard.set("XXYYZZ", forKey: “UserID")

// Int get let userId = UserDefaults.standard.integer(forKey: “UserID")

// 0 if userId == 0 { print("NG!!") }

!

!

// class UserDefaultsWrapper { var userName: String { set { UserDefaults.standard.set(newValue, forKey: "userName") } get { return UserDefaults.standard.string(forKey: "userName")! } } }

// let isUserLoggedInKey = "isUserLoggedIn"

UserDefaults.standard.set(true, forKey: isUserLoggedInKey) UserDefaults.standard.bool(forKey: isUserLoggedInKey)

// Enum enum Account : String { case isUserLoggedIn

// .rawValue // "isUserLoggedIn"

}

// Set UserDefaults.standard .set(true, forKey: Account.isUserLoggedIn.rawValue)

// Get UserDefaults.standard .bool(forKey: Account.isUserLoggedIn.rawValue)

protocol BoolDefaultSettable { associatedtype BoolKey : RawRepresentable } extension BoolDefaultSettable where BoolKey.RawValue == String { // Setter func set(_ value: Bool, forKey key: BoolKey) { let key = key.rawValue UserDefaults.standard.set(value, forKey: key) } // Getter func bool(forKey key: BoolKey) -> Bool { let key = key.rawValue return UserDefaults.standard.bool(forKey: key) } } extension UserDefaults : BoolDefaultSettable { enum BoolKey : String { case isUserLoggedIn } } UserDefaults.standard.set(true, forKey: .isUserLoggedIn) UserDefaults.standard.bool(forKey: .isUserLoggedIn)

class UserDefalutsProxy<Type> { let userDefaults: UserDefaults let key: String let defaultValue: Type init(userDefaults: UserDefaults = UserDefaults.standard, key: String, defaultValue: Type) { self.userDefaults = userDefaults self.key = key self.defaultValue = defaultValue } var value: Type { get { return self.userDefaults.object(forKey: self.key) as? Type ?? self.defaultValue } set { self.userDefaults.set(newValue, forKey: self.key) } } }

class UserDefalutsProxy<Type> { // UserDefaults Key let userDefaults: UserDefaults let key: String ... }

class UserDefalutsProxy<Type> { ... // UserDefaults var value: Type { get { return self.userDefaults.object(forKey: self.key) as? Type ?? self.defaultValue } set { self.userDefaults.set(newValue, forKey: self.key) } } }

struct AppConfig {

static var userName: UserDefalutsProxy<String> { get { // #function // Key return UserDefalutsProxy<String>(key: #function, "--") } }

static var mailAddress: UserDefalutsProxy<String?> { get { return UserDefalutsProxy<String?>(key: #function, "--") } } }

AppConfig.userName.value = "hoge" let mailAddress = AppConfig.mailAddress.value print(mailAddress)

var mailAddress: UserDefalutsProxy<String?> { get { return UserDefalutsProxy<String?>(key: #function, "--") } }

let date = Date() UserDefaults.standard.set(date, forKey: "hoge") print(UserDefaults.standard.object(forKey: "hoge")) // Optional(2017-03-15 04:16:03 +0000)

UserDefaults.standard.set(nil, forKey: "hoge") print(UserDefaults.standard.object(forKey: "hoge")) // Optional(<62706c69 73743030 d4010203 04050608 09582476 …>)

UserDefaults.standard.set(Optional<Int>.none, forKey: "hoge") print(UserDefaults.standard.object(forKey: "hoge")) // nil

class UserDefalutsProxy2<Type> { var value: ValueType { set { if newValue == nil { self.remove() } else{ self.userDefaults.set(newValue, forKey: self.key) } } } func remove() { self.userDefaults.removeObject(forKey: key) } }

class UserDefalutsOptionalProxy<Type> { ... var value: Type? { // Optional get { return self.userDefaults.object(forKey: self.key) as? Type } set { if let newValue = nil { self.userDefaults.set(newValue, forKey: self.key) } else { self.remove() } } } func remove() { self.userDefaults.removeObject(forKey: self.key) } }

struct AppConfig { static var userName: UserDefalutsProxy<String> { get { return UserDefalutsProxy<String>(key: #function, "--") } } static var mailAddress: UserDefalutsOptionalProxy<String> { get { return UserDefalutsOptionalProxy<String>(key: #function) } } }

AppConfig.userName.value = “hoge" AppConfig.mailAddress.value = nil

class UserDefalutsEnumProxy<Type>: UserDefalutsProxy<Type> where Type: RawRepresentable { ... override var value: Type { get { guard let rawValue = self.userDefaults.object(forKey: self.key) as? Type.RawValue else { return self.defaultValue } return Type.init(rawValue: rawValue) ?? self.defaultValue } set { let rawValue = newValue.rawValue self.userDefaults.set(rawValue, forKey: self.key) } } }

class DuplicateKeyChecker { private static var keys: [String] = [] static var isCheckDuplicateKey: Bool = false fileprivate static func checkProc(key: String) { guard self.isCheckDuplicateKey else { return } assert(!self.keys.contains(key), "Duplicate defaults key: \(key)") self.keys.append(key) } }

class UserDefalutsProxy<Type> { init(userDefaults: UserDefaults = UserDefaults.standard, key: String, _ defaultValue: ValueType) { DuplicateKeyChecker.proc(key) self.userDefaults = userDefaults self.key = key self.defaultValue = defaultValue } ... }

// String typealias StringProxy = UserDefalutsProxy<String>

typealias StringOptProxy = UserDefalutsOptionalProxy<String>

typealias StringArrayProxy = UserDefalutsProxy<[String]>

typealias StringArrayOptProxy = UserDefalutsOptionalProxy<[String]>

#if DEBUG DuplicateKeyChecker.isCheckDuplicateProxyName = true #endif

struct AppConfig { static var userName = StringProxy(key: "userName", "--") static var mailAddress = StringOptProxy(key: "mailAddress") } AppConfig.userName.value = "hoge" AppConfig.mailAddress.value = nil

enum State: Int { case sleep case active }

struct AppConfig { static var state = UserDefalutsEnumProxy<State>(key: "state", .sleep) }

AppConfig.state.value = .active

protocol UserDefaultsConvertibleEnumType: RawRepresentable { static var userDefalutsProxy: UserDefalutsEnumProxy<Self> { get } static var current: Self { get set } }

extension UserDefaultsConvertibleEnumType { static var current: Self { get { return Self.userDefalutsProxy.value } set { Self.userDefalutsProxy.value = newValue } } }

enum State: Int, UserDefaultsConvertibleEnumType {

case sleep case active static let userDefalutsProxy = UserDefalutsEnumProxy<State>… }

State.current = .active if State.current == .sleep { print("zzz") }

extension UserDefalutsProxy { func observable() -> Observable<Type> { let observable1 = Observable.just(self.value) let observable2 = self.userDefaults .rx .observe(Type.self, self.key, options: .new, retainSelf: true) .map { _ in self.value } return observable1.concat(observable2) } }