NSUserDefaultsを便利にする。

#NSUserDefaultsが不便
今のNSUserDefaultsの不満
Objectを取り出して　→　nilチェックして　→　キャストして　→　やっと使える。
つまり　

```swift:
//==================================
//保存時
let defaults = NSUserDefaults()
defaults.setObject("Hello World",forKey:"sample")
//==================================
//読み込み時
let defaults = NSUserDefaults()
if let data = defaults.objectForKey("sample") as? String{
    ...
}


```

＿人人人人人人人人＿
＞　めんどくさい　＜
￣Y^Y^Y^Y^Y^Y^Y^Y￣

#こうする

```swift
 let Info = RMInfo()
 
 let data = ["a","b","c"]
 Info.save(data,id:"obj")
=========================================
 let object = Info.load([String].self,id:"obj")//["a","b","c"]
 
 object.count //3

Info.load(String.self,"sample")//"" 
//保存された値がない場合は,Intなら0,Stringなら"",Arrayなら[]を返す。


```
　
#実装

```swift
import UIKit

protocol defaultValueProtocol {
    associatedtype U
    static var defaultValue:U{get}
}

class RMInfo: NSObject {
    private var defaults = NSUserDefaults()

    func load<T: defaultValueProtocol>(type:T.Type,id:String)->T.U{
        if let object = defaults.objectForKey(id) as? T.U{
            return object
        }else{
            return T.defaultValue
        }
    }
    func save(object:AnyObject,id:String){
        defaults.setObject(object, forKey: id)
        defaults.synchronize()
    }
    func resetByType<T :defaultValueProtocol>(type:T.Type){
        let dict = defaults.dictionaryRepresentation()
        for key in dict.keys {
            if defaults.objectForKey(key) is T {
                defaults.removeObjectForKey(key)
            }
        }
        defaults.synchronize()
    }
    func resetByContainsName(containsName:String){
        let dict = defaults.dictionaryRepresentation()
        for key in dict.keys {
            if key.containsString(containsName){
                defaults.removeObjectForKey(key)
            }
        }
        defaults.synchronize()
    }
    func resetAll(){
        let dict = defaults.dictionaryRepresentation()
        for key in dict.keys {
            defaults.removeObjectForKey(key)
        }
        defaults.synchronize()
    }
}


extension Int:defaultValueProtocol{
    typealias U = Int
    static var defaultValue: Int.U{
        return 0
    }
}
extension Bool:defaultValueProtocol{
    typealias U = Bool
    static var defaultValue: Bool.U{
        return false
    }
}
extension Double:defaultValueProtocol{
    typealias U = Double
    static var defaultValue: Double.U{
        return 0.0
    }
}
extension Float:defaultValueProtocol{
    typealias U = Float
    static var defaultValue: Float.U{
        return 0.0
    }
}
extension CGFloat:defaultValueProtocol{
    typealias U = CGFloat
    static var defaultValue: CGFloat.U{
        return 0.0
    }
}
extension String:defaultValueProtocol{
    typealias U = String
    static var defaultValue: String.U{
        return ""
    }
}
extension Array :defaultValueProtocol{
    typealias U = Array
    static var defaultValue: Array.U{
        return []
    }
}
extension Dictionary :defaultValueProtocol{
    typealias U = Dictionary
    static var defaultValue: Dictionary.U{
        return [:]
    }
}
extension NSURL: defaultValueProtocol{
    typealias U = NSURL
    static var defaultValue: NSURL.U{
        return NSURL()
    }
}

```

他にも保存したい型があるなら

```swift
extension 保存したい型:defaultValueProtocol{
    typealias U = 保存したい型
    static var defaultValue: 保存したい型.U{
        return デフォルトの値
    }
}
```

で追加可能



#RM


Swiftのジェネリクスが便利すぎて惚れそう。