UIImageをUserDefaultsに保存するためのextensionを作った

## はじめに
UserDefaultsを使い値を永続的に保存することで、アプリの設定などを端末に保存することができます。しかしUserDefaultsで保存できる値の方には限りがあります。
UserDefaultsで保存することができる値は以下になります。

| 型                        | 保存時の処理 | 参照時の処理        |
|---------------------------|--------------|---------------------|
| 配列型:[Any]              | set:forKey:  | array:forKey        |
| 真偽型:Bool               | set:forKey:  | bool:forKey         |
| データ型:Data             | set:forKey:  | data:forKey         |
| 辞書型:[String:Any]       | set:forKey:  | dictionary:forKey   |
| 浮動小数点型:Float        | set:forKey:  | float:forKey:       |
| 整数型:Int                | set:forKey:  | integer:forKey:     |
| オブジェクト型:Any        | set:forKey:  | object:forKey:      |
| 文字列型配列:[String]     | set:forKey:  | stringArray:forKey: |
| 文字列型:String           | set:forKey:  | string:forKey:      |
| 倍精度浮動小数点型:Double | set:forKey:  | double:forKey:      |
| URL型:URL                 | set:forKey:  | url:forKey:         |

[参照記事](https://hitoto28.hatenablog.com/entry/2018/07/09/020000)

以上のことから、例えばアプリで画像(UIImage型)を永続化して保存したい場合はUserDefaultsを利用して保存することができません。
ならばどうするかというと一般的に考えられる方法として、
UIImage型からData型へ変換してUserDefaultsへ保存し、取り出し後にUIImage型へ再変換する方法があります。

```swift
// UserDefaultsの宣言
let ud = UserDefaults.standard

// UserDefaultsへ保存するとき
// UIImageをData型へ変換
let hogeImage = UIImage(named: "hoge.png")
let data = hogeImage.pngData()
// UserDefaultsへ保存
ud.set(data, forKey: "image")

//-----------------------------------------------------------

// UserDefaultsから参照するとき
// UserDefaultsから参照する
let hogeData = ud.data(forKey: "image")
// Data型からUIImage型へ変換
let hogeImage = UIImage(data: hogeData)
```

こんなかんじだと思います。

しかし、いちいち上記のコードを書いて変換して保存して取り出して変換してとしていたら大変なので、UserDefaultsの機能を拡張して一発で変換保存参照変換できるようにします。

## 解決策

UserDefaultsのextension で下記のメソッドを追加します。

```swift

extension UserDefaults {
    // 保存したいUIImage, 保存するUserDefaults, Keyを取得
    func setUIImageToData(image: UIImage, forKey: String) {
        // UIImageをData型へ変換
        let nsdata = image.pngData()
        // UserDefaultsへ保存
        self.set(nsdata, forKey: forKey)
    }
    // 参照するUserDefaults, Keyを取得, UIImageを返す
    func image(forKey: String) -> UIImage {
        // UserDefaultsからKeyを基にData型を参照
        let data = self.data(forKey: forKey)
        // UIImage型へ変換
        let returnImage = UIImage(data: data!)
        // UIImageを返す
        return returnImage!
    }
    
}
```

## 実用例

```swift:ViewController
class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    // UserDefaultsの宣言
    let ud = UserDefaults.standard
    // 保存するUIImage
    var hogeImage: UIImage = UIImage(named: "spiderman.jpg")!
  
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        // 保存するとき
        // UserDefaultsにsetする(保存するUIImage, 宣言したUserDefaults, Keyの文字列)
        ud.setUIImageToData(image: hogeImage, forKey: "image")
        

        // 参照するとき
        // UIImage型の変数に参照する(宣言したUserDefaults, Keyの文字列)
        hogeImage = ud.image(forKey: "image")
        // UIImageViewに表示
        imageView.image = hogeImage
    }
}
```

こんな感じです。
多少は便利になったはず...
extensionは使いこなせばマジ便利

ほんとはRealmなどのデータベースを使うのが一番早いです...
それでは。