【Swift】NSKeyedArchiverでクラスをそのままUserDefaultsに保存する

この記事からわかること

  • Swift/NSKeyedArchiverクラスそのまま保存する方法
  • NSKeyedArchiver/NSKeyedUnarchiverクラスとは?
  • 独自のクラスをData型変換する方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

参考文献:公式リファレンス:Caching on Swift Using NSKeyedArchiver

NSKeyedArchiverクラスとは?

公式リファレンス:NSKeyedArchiverクラス

class NSKeyedArchiver : NSCoder

NSKeyedArchiverオブジェクトのデータをキーによって参照されるアーカイブに保存するエンコーダークラスです。オブジェクトをファイルなどへの保存に適した、アーキテクチャに依存しない形式にエンコードする方法を提供しています。

独自に定義したクラスも構造を保ったままData型にエンコードすることでコード内での扱いやすさも向上します。

NSKeyedUnarchiverクラスとは?

公式リファレンス:NSKeyedUnarchiverクラス

class NSKeyedUnarchiver : NSCoder

NSKeyedUnarchiverキーによって参照されるアーカイブからデータを復元するデコーダークラスです。NSKeyedArchiverと逆側の処理を担っています。

クラスをそのままUserDefaultsに保存する

この2つのクラスを使用することで独自に定義したクラスをUserDefaultsに保存し、取得することができるようになります。

流れ

  1. 独自クラスの定義
  2. NSObject/NSCodingへの準拠
  3. encode(with coder: NSCoder)/required init?(coder: NSCoder)の実装
  4. クラスをエンコードしてアーカイブを作成しUserDefaultsに保存
  5. UserDefaultsから取り出したアーカイブをデコードしてクラスに変換

まずは独自のクラスを定義します。

class User {
    var id:Int
    var name:String
    
    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
}

NSObjectNSCodingに準拠させます。NSCodingに準拠させたことでencode(with coder: NSCoder)メソッド(エンコード処理用)とrequired init?(coder: NSCoder)(デコード処理用)の実装が必須となります。

class User:NSObject,NSCoding {
    var id:Int
    var name:String
    
    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
    
    func encode(with coder: NSCoder) {
        coder.encode(id,forKey: "id")
        coder.encode(name,forKey: "name")
    }
    
    required init?(coder: NSCoder) {
        id = coder.decodeObject(forKey: "id") as! Int
        name = coder.decodeObject(forKey: "name") as! String
    }
}

あとは保存したいクラスをアーカイブに変換しUserDefaultsに保存する処理UserDefaultsに保存されているアーカイブをデコードしてクラスに変換する処理を書けば完成です。

struct ContentView: View {
    
    var userDefaults = UserDefaults.standard
    
    func setUser(){
        let user = User(id: 1, name: "ame")
        let data = try? NSKeyedArchiver.archivedData(withRootObject: user, requiringSecureCoding: false)
        userDefaults.set(data, forKey: "user")
    }
    func getUser(){
        let obj = userDefaults.data(forKey: "user")!
        let user = NSKeyedUnarchiver.unarchiveObject(with: obj) as! User
        print(user.id)
        print(user.name)
        
    }
    
    var body: some View {
        VStack{
            Button {
                getUser()
            } label: {
                Text("getUser")
            }
            
            Button {
                setUser()
            } label: {
                Text("setUser")
            }
        }
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index