enumでNSUserDefaultsを便利に

  • 42
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

リテラルを使いたくない

Swiftのenumを使ってNSUserDefaultsを便利にする方法を思いつきました。 既出だったらごめんなさい。

enum MyUserDefaults: String {
    case Name = "Name"
    case Age = "Age"
    case Height = "Height"
    case Weight = "Weight"

    func set(value: AnyObject) {
        NSUserDefaults.standardUserDefaults().setObject(value, forKey: self.toRaw())
    }

    func get() -> AnyObject? {
        return NSUserDefaults.standardUserDefaults().objectForKey(self.toRaw())
    }
}

これで、値の設定と取得を以下のように行うことができます。

// 設定
MyUserDefaults.Name.set("田中太郎")
MyUserDefaults.Age.set(20)
MyUserDefaults.Height.set(171.65)
MyUserDefaults.Weight.set(65.63)

// 取得
if let name = MyUserDefaults.Name.get() as? String {
    name //田中太郎
}

if let age = MyUserDefaults.Age.get() as? Int {
    age //20
}

StringもIntegerもFloatもstructですが、AnyObjectに渡す時点でNSStringやNSNumberに暗黙的に変換されるようです。そのため、基本的にはどんな型でもsetObjectとobjectForKeyでうまくいくみたいです。

AnyObjectを使いたくない

Stringしか使わない場合も結構あると思います。その時はStringに限定してしまうのもアリかもしれません。たいして変わりませんが…

func set(value: String) {
    NSUserDefaults.standardUserDefaults().setObject(value, forKey: self.toRaw())
}

func get() -> String? {
    return NSUserDefaults.standardUserDefaults().stringForKey(self.toRaw())
}

もちろん他の型で置き換えたり複数実装することも可能です。

もっとリテラルを使いたくない

保存されるデータの可読性を無視するなら、こうすることもできます:

enum MyUserDefaults: Int {
    case Name, Age, Height, Weight

    func set(value: AnyObject) {
        NSUserDefaults.standardUserDefaults().setObject(value, forKey: String(self.toRaw()))
    }

    func get() -> AnyObject? {
        return NSUserDefaults.standardUserDefaults().objectForKey(String(self.toRaw()))
    }
}

そもそも保存されているデータを直接扱う機会もあんまり無いと思うのでこれでいいと思います。
一応、実際使用する際はキー被りを避けるためにPrefixとか付けたほうがいいんじゃないですかね。

リテラルを使わなくてよい!

NSUserDefaults以外にも、NSFileManagerとかUITableViewCellとか、いろいろ活用できそうな気がします。
Swiftのenumは強力ですね。