Open1

Swift: UserDefaultsなどからEnumで取り出す

kabeyakabeya

UserDefaultsなどのストレージからEnum型の値を読み書きしたいことがあります。

Enumにローバリューを設定しておけば、ジェネリックを使って以下のように書けます。

    func getEnumFromUserDefaults<T: RawRepresentable>(forKey: String, defaultValue: T) -> T where T.RawValue == String {
        guard let str = UserDefaults.standard.string(forKey: forKey) else {
            return defaultValue
        }
        let enumValue = T(rawValue: str)
        return enumValue ?? defaultValue
    }
    
    func setEnumToUserDefaults<T: RawRepresentable>(forKey: String, value: T) where T.RawValue == String {
        UserDefaults.standard.set(value.rawValue, forKey: forKey)
    }

この例ではRawValue == Stringにしています。
Intとかのバリエーションも以下のように作れますが、UserDefaults.standard.integer(forKey:)floatとかdoubleとかboolも)は、stringと違い、キーがない場合nilではなく0を返してくるので若干やっかいです。以下のコードはキーの有無によらずそのまま取得していますが、キーなしが0で困る場合は、stringなどnilを返すバージョンで取り出してからIntに変換するというステップを踏む必要があるでしょう。

    func getEnumFromUserDefaults<T: RawRepresentable>(forKey: String, defaultValue: T) -> T where T.RawValue == Int {
        let int = UserDefaults.standard.integer(forKey: forKey)
        let enumValue = T(rawValue: int)
        return enumValue ?? defaultValue
    }
    
    func setEnumToUserDefaults<T: RawRepresentable>(forKey: String, value: T) where T.RawValue == Int {
        UserDefaults.standard.set(value.rawValue, forKey: forKey)
    }

使い方は以下のようになります。

enum MyEnum: String {
   case value1
   case value2
   case value3
}

let e = getEnumFromUserDefaults(forKey: "test", defaultValue: MyEnum.value1)