Xcode
Swift
UserDefaults
エンジニア
swift4

[iOS, Swift4] カスタムクラスをData型に変換する(UserDefaultsにカスタムクラスの配列を保存する)

カスタムクラスをData型に変換する必要性

例えばUserDefaultsを使用する場合、カスタムオブジェクトをNSDataに変換する必要があります :)

なぜかというと、UserDefaultsで保存できる型は NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary となっているからです。

これ以外の型を保持させたい場合は一旦NSData型に変換してから保持し、読み込む際はNSData型として読み込んだ後に型変換を行う必要があります。

以下では「UserDefaultsにてカスタムクラスの配列を保存、読み込む」という具体的なケースで、Swift4でカスタムクラスをData型に変換する処理を見ていきます😄

流れ

iOS ではシリアライズすることをアーカイブ、デシリアライズすることをアンアーカイブといいます。
アーカイブのためのクラスとして NSKeyedArchiver クラス
アンアーカイブのためのクラスとして NSKeyedUnarchiver クラスがあります。

概要図 2018-05-04 13.26.58.png

UserDefaultsにカスタムクラスの配列を保存・読み込みをする

まず、独自に作成するカスタムクラスを定義します。

<ポイント>
NSObject, NSCodingを継承する
エンコード、デコード処理を記述する

class SomeObj: NSObject, NSCoding {

    var word: String!
    var date: String!

    init(word: String, date: String) {
        self.word = word
        self.date = date
    }

    required init?(coder aDecoder: NSCoder) {
        self.word = aDecoder.decodeObject(forKey: "word") as! String
        self.date = aDecoder.decodeObject(forKey: "date") as! String
    }

    func encode(with aCoder: NSCoder) {
        if let word = word { aCoder.encode(word, forKey: "word") }
        if let date = date { aCoder.encode(date, forKey: "date") }
    }
}

保存処理ではNSKeyedArchiver.archivedDataを使用します

var someObjArray = [SomeObj]()
let someObj = SomeObj(word: "hoge", date: "2000/01/01")

someObjArray.insert(someObj, at: 0) 

UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: someObjArray), forKey: "someObjs")

読み込み処理では、一度Data型で読み込んだものをNSKeyedUnarchiver.unarchiveObjecを使用してアンアーカイブ(デシリアライズ)します

func loadSomeObjs() -> [someObj]?{
        if let loadedData = UserDefaults().data(forKey: "someObjs") {
            let someObjs = NSKeyedUnarchiver.unarchiveObject(with: loadedData) as! [SomeObj]
            return someObjs
        }else {
            return nil
        }
}

これでUserDefaultsにカスタムクラスの配列を保存したり、読み込んだりできるようになります!