iOS
 Computer >> コンピューター >  >> プログラミング >> iOS

【Swift】NSUserDefaultsにカスタムオブジェクトを保存・復元する方法を徹底解説

この記事では、アプリケーション内でカスタムオブジェクトをNSUserDefaultsに保存する方法を解説します。保存手順を学ぶ前に、まず「カスタムオブジェクトとは何か」を確認しておきましょう。

カスタムオブジェクトとは、Int、Double、Stringといったネイティブなデータ型ではなく、独自に定義したクラスや構造体などのデータのことを指します。NSUserDefaultsへのデータ保存は、次の3つのステップで行います。

1. カスタムオブジェクトの作成

まず、name(名前)とage(年齢)の2つの変数を持つ、Personというカスタムクラスを作成します。NSUserDefaultsに保存するには、クラスがNSCodingプロトコルに準拠している必要があります。

class Person: NSObject, NSCoding {
    var name: String
    var age: Int
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    required convenience init(coder aCoder: NSCoder) {
        let name = aCoder.decodeObject(forKey: "name") as! String
        let age = aCoder.decodeInteger(forKey: "age")
        self.init(name: name, age: age)
    }
    func encode(with acoder: NSCoder) {
        acoder.encode(age, forKey: "age")
        acoder.encode(name, forKey: "name")
    }
}

encode(with:)メソッドではオブジェクトの各プロパティをエンコードし、required init(coder:)ではデコード時の復元処理を定義しています。この2つがNSCoding準拠の必須実装です。

2. カスタムオブジェクトのエンコード(保存)

次に、Personオブジェクトの配列peopleを作成し、サンプルデータで初期化します。オブジェクトを作成したら、NSKeyedArchiverを使ってアーカイブし、その結果をUserDefaultsに保存します。

let people = [
    Person.init(name: "P1", age: 1),
    Person.init(name: "P2", age: 2),
    Person.init(name: "P3", age: 3),
]
let encoded = NSKeyedArchiver.archivedData(withRootObject: people)
UserDefaults.standard.set(encoded, forKey: "encodedData")

これで、アーカイブされたオブジェクトをUserDefaultsに保存できました。続いて、保存したデータを復元(アンアーカイブ)して出力してみましょう。

3. カスタムオブジェクトのデコード(復元)

NSKeyedArchiverと対になるNSKeyedUnarchiverを使用することで、保存したデータを元のオブジェクトに復元できます。

let decoded = UserDefaults.standard.object(forKey: "encodedData") as! Data
let decodedPeople = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Person]

これで、decodedPeopleオブジェクトには、ステップ2で作成したPersonオブジェクトの配列が格納されています。復元したオブジェクトに対して、任意の処理を自由に行うことが可能です。

ViewControllerの完全なコード

ここまでの処理をまとめると、ViewControllerファイルは以下のようになります。

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let people = [
            Person.init(name: "P1", age: 1),
            Person.init(name: "P2", age: 2),
            Person.init(name: "P3", age: 3),
        ]
        let encoded = NSKeyedArchiver.archivedData(withRootObject: people)
        UserDefaults.standard.set(encoded, forKey: "encodedData")
        print("data decoded, encoding now")
        let decoded = UserDefaults.standard.object(forKey: "encodedData") as! Data
        let decodedPeople = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Person]
        print(decodedPeople)
    }
}

最後のprint文にブレークポイントを設定してコードを実行し、実行時にデバッグコンソールで次のコマンドを入力します。

po decodedPeople.first?.name

すると、以下のような結果が得られます。

Optional<String>
- some : "P1"

補足:非推奨となったAPIについて

なお、archivedData(withRootObject:)やunarchiveObject(with:)はiOS 12以降で非推奨(deprecated)となっています。最新の環境では、セキュアコーディングを有効にしたarchivedData(withRootObject:requiringSecureCoding:)や、unarchivedObject(ofClass:from:)の使用が推奨されるため、新規開発ではこちらを採用するとよいでしょう。

最終的な実行結果は以下のようになります。

【Swift】NSUserDefaultsにカスタムオブジェクトを保存・復元する方法を徹底解説

  1. 【Android】カスタムオブジェクトをSerializable(シリアライズ可能)にする方法を解説

    カスタムオブジェクトをSerializableにするには?この記事では、Androidアプリ開発において、独自に定義したカスタムクラスのオブジェクトをSerializable(シリアライズ可能)にする方法を、実際のコード例とともにステップ形式で解説します。オブジェクトをIntent経由で他の画面へ渡したり、ファイルやネットワーク越しに保存・送信したりする場合、シリアライズの仕組みは欠かせません。ステップ1:新規プロジェクトを作成するAndroid Studioを起動し、メニューから「File」→「New Project」を選択します。必要な項目を入力して、新しいプロジェクトを作成しましょう。ス

  2. 【Android】カスタムオブジェクトをParcelableにする方法をサンプルコードで解説

    このチュートリアルでは、Androidアプリ開発において、独自に定義したカスタムクラス(カスタムオブジェクト)をParcelable対応にする方法を、サンプルコードとともにわかりやすく解説します。 Parcelableとは、オブジェクトを直列化してIntentやBundle経由でActivity間などに受け渡すためのAndroid標準インターフェースです。Java標準のSerializableよりも高速に動作するため、Android開発ではParcelableの実装が推奨されています。 手順1:新規プロジェクトを作成する Android Studioを起動し、メニューから「File」→「New