【Swift2.x】独自クラスのプロパティの独自クラスや、配列の独自クラスをNSUserDefaultで保存する方法

データ永続化の方法は色々ありますが、NSUserDefaultの利点はアプリ起動時にデータをメモリに読んでからアクセスするので、高速に読込ができる点にあります。今回は、タイトル画面でステージ情報を読み込んでNSUserDefaultに保存し、次の画面で読み込む動作を作ってみます。

独自クラスのオブジェクトをNSUserDefaultで保存/読込する方法は調べると色々出てくるのですが、独自クラスの中に独自クラスがある入れ子状態の場合や、配列の独自クラスはどうするのか?という情報を探しても的確な答えが見つからなかったので、自分で試してみました。

制作環境

  • Xcode7.2.1
  • Swift2
  • SpriteKit

 

プロジェクトファイルの説明

新規プロジェクトで、Single Viewプリセットを選びます。

画面1(FirstScene)でStageManagerオブジェクトを作成してNSUserDefaultに保存します。
画面遷移させて画面2(SecondScene)を呼び出し、今度はNSUserDefaultに保存されているStageManagerオブジェクトを読み込みます。画面遷移前に保存、遷移後に読込とする事で、ちゃんと保存/読込ができているか確認できます。

スクリーンショット 2016-06-30 18.30.30

 

独自クラスの配列に入れた独自クラスをNSUserDefaultで保存する

通常のNSUserDefaultの使い方に加えて、やる事は2つだけです。

  • 独自クラスの、NSDataへのアーカイブ/アンアーカイブ処理(NSUserDefaultで保存/読込処理をする場所に書く)
  • シリアライズとデシリアライズ(NSObjectの継承とNSCodingプロトコルを適用した独自クラス内に書く)

ポイントは、独自クラスのプロパティに独自クラスがある場合、入れ子になってる独自クラスのプロパティ全てでシリアライズとデシリアライズ処理を実装する事です。

 

SpriteKitを使う準備

SpriteKitを使うので、デフォルトで最初に読み込まれるViewControllerのviewをSKViewにして、FirstSceneを表示させます。

 

独自クラス、StageとStageManagerの作成

個別のステージ情報を管理するクラスを作成します。
独自クラスをNSUserDefaultで保存するには、シリアライズとデシリアライズの処理を実装する必要があります。

まずは、独自クラスにNSObjectを継承させて、NSCodingプロトコルを適用します。
ドットインストール風に言うと、「この2つは、NSUserDefaultの保存/読込に対応させるための決まり文句です!」
このNSCodingプロトコルを唱えると、func encodeWithCoder(aCoder: NSCoder) とrequired init(coder: NSCoder) の2つのメソッドを必ず作らなければいけません。この2つのメソッドで、シリアライズとデシリアライズを実装します。メソッドの中身は、下のソースを参考にしてください。

次に、個別のステージ情報を取得したり、ステージ一覧を管理するクラスを作成します。
この様に、独自クラスの中に独自クラスのプロパティが入っている場合は、両方のクラスでNSObjectの継承とNSCodingプロトコルを適用させなければなりません。片方だけだと、エラーになります。

 

画面遷移の作成

画面1として表示させるSKSceneを作成します。
ViewControllerから最初に呼ばれるゲームタイトル画面を想定しています。この最初の画面で、サーバーからダウンロードしたJSONファイルからステージ情報を全て読み込んでNSUserDefaultに保存しておく事で、画面が変わったりアプリを終了させたりしてもステージ情報へ高速にアクセスできます。

SpriteKitを使用しているので、各画面はSKSceneで作っています。SpriteKitを使わず、通常のアプリ制作の様にStoryboardで画面遷移を作る場合は、各画面のViewControllerに下記の処理を実装します。

画面1として表示させるSKSceneを作成します。ステージ選択画面を想定しています。
画面遷移後に、保存されたStageManagerを読み込みます。