LoginSignup
2
3

More than 3 years have passed since last update.

[Swift] カスタムstructを簡単にUserDefaultsに保存する <NSCodingは捨てよう>

Last updated at Posted at 2020-07-04

NSCoding意味わかんない

意味分かんない

UserDefaultsに保存できるデータ型

UserDefaultsに保存できるデータ型は
数値型
文字列型
真偽型
データ型(Data、NSData)
とこれらを値とする
配列型
辞書型(キーは文字列型に限る)
のみとなっています。

非対応のデータ型を保存する方法 その1

保存できるデータ型(Data,NSDataを除く)に変換する。

例えば CGRect を数値の配列に変換して保存するなどです。

extension UserDefaults {
  func set(_ value: CGRect, forKey key: String) {
    let rectDataArray = [value.origin.x, value.origin.y, value.width, value.height]
    set(rectDataArray, forKey: key)
  }

  func cgRect(forKey key: String) -> CGRect? {
     guard let rectDataArray = array(forKey: key) as? [CGFloat] else { return nil }
     guard rectDataArray.count == 4 else { return nil }
     return CGRect(x: rectDataArray[0], y: rectDataArray[1], width: rectDataArray[2], height: rectDataArray[3])
  }
}

非対応のデータ型を保存する方法 その2

その1で数値や文字列にするのが難しいデータ型の場合はデータ(NSData/Data)に変換して保存します。
その助けをするのがNSCodingプロトコルとNSKeyedArchiver/NSKeyedUnarchiverです。

これをやりたくない趣旨のエントリですので詳細は省きます。

非対応のデータ型を保存する方法 その3

実はSwiftにはNSCodingを使わなくてもデータ型をデータ(NSData/Data)に簡単に変換してもらえる便利なものがあります。
Codable = Encodable & Decodable
です。

Codableへの準拠は変わったデータ型ではない限り、コンパイラが自動で行ってくれるのがすごくうれしい!

これを使わない手はありません。
ここではCoderとしてJSON(En/De)coderを使用しました。

extension UserDefaults {
  func setEncoded<T: Encodable>(_ value: T, forKey key: String) {
    guard let data = try? JSONEncoder().encode(value) else {
       print("Can not Encode to JSON.")
       return
    }

    set(data, forKey: key)
  }

  func decodedObject<T: Decodable>(_ type: T.Type, forKey key: String) -> T? {
    guard let data = data(forKey: key) else {
      return nil
    }

    return try? JSONDecoder().decode(type, from: data)
  }
}

CGRectを保存してみましょう。
CGRectはCodableに準拠してますので特に何か付け加える必要はありません。

let cgRect = CGRect(x: 0, y: 0, width: 100, height: 100)

UserDefaults.standard.setEncoded(cgRect, forKey: "KEY")

// storedCGRect's type is CGRect.
let storedCGRect = UserDefaults.standard.decodedObject(CGRect.self, forKey: "KEY")

はい、簡単、型安全。

とくにまとめることはない

簡単さと標準準拠を肝としたのでUserDefaultsのKeyがStringで危険なままですが、そのあたりは別にいろいろあるのでググったりなんだりすればいいと思う。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3