【Swift5】自作クラス(と配列)をUserDefaultsに簡単に保存する


この記事では自作クラスをUserDefaultsに簡単に保存する関数を紹介します。

ちょっとしたデータの保存はUserDefaultsを使うのが一般的ですが、保存できる型が限られています。 対応していない場合はDataに変換して保存する必要があり、少し面倒です。 そこで今回は関数(と言っても大したことはないですが)を作成しました。

保存したいクラス

    class Friend: NSObject, NSCoding {
      var name:String?
      var age:Int?

      init(_ name: String?, _age: Int?) {
        self.name = name
        self.age= age
      }

      func encode(with coder: NSCoder) {
          coder.encode(name, forKey: "name")
          coder.encode(age, forKey: "age")
      }

      required init?(coder: NSCoder) {
          name = coder.decodeObject(forKey: "name") as? String
          age = coder.decodeObject(forKey: "age") as? Int
      }
    }

ポイントは1行目に: NSObject, NSCodingと加えることと、エンコード・デコードの部分を用意することです。

保存、取得用の関数

通常

    extension UserDefaults {
      func getFriend(_ key:String) -> Friend? {
          if let storedData = UserDefaults.standard.object(forKey: key) as? Data {
              if let unarchivedObject = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(storedData) as? Friend {
                  return unarchivedObject
              }
          }
          return nil
      }

      func setFriend(_ friend:[Friend],_ key:String) {
          let data = try! NSKeyedArchiver.archivedData(withRootObject: friend, requiringSecureCoding: false)
          UserDefaults.standard.set(data, forKey: key)
      }
    }

配列の場合

    extension UserDefaults {
      func getFriends(_ key:String) -> [Friend]? {
          if let storedData = self.object(forKey: key) as? Data {
              if let unarchivedObject = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(storedData) as? [Friend] {
                  return unarchivedObject
              }
          }
          return nil
      }

      func setFriends(_ friends:[Friend],_ key:String) {
          let data = try! NSKeyedArchiver.archivedData(withRootObject: friends, requiringSecureCoding: false)
          self.set(data, forKey: key)
      }
    }

使用方法

この関数はUserDefaultsの拡張なので、このように使います。

通常

    let boy = Friend.init("Tom",25)
    //保存
    UserDefaults.standard.setFriend(boy,"friend")
    //取得
    let friend = UserDefaults.standard.getFriend("friend")

配列の場合

    let boys = [Friend.init("Tom",25),Friend.init("Bob",18)]
    //保存
    UserDefaults.standard.setFriends(boys,"friends")
    //取得
    let friends = UserDefaults.standard.getFriends("friends")

おわりに

通常のUserDefaultsのように1行で使えるので、コードが見やすくなると思います。

間違っている部分があったら教えていただけると助かります🙇‍♂️

Comments

Show Comments