[XCODE] Objective-Cでアーカイブとアンアーカイブを行う
こんにちは、@yoheiMuneです。
今日は、Objective-Cの色々な型(UIViewやNSArrayなど)をアーカイブして、状態をバイナリーデータとして 保存する方法と、そのデータをアンアーカイブして元の形に戻す方法をブログに書きたいと思います。
これを行うことで、現在の変数の状態をそのまま(型によっては一部情報が削除されますが)に、 次のアプリ起動時などに使うことが出来るようになります。
「変数の内容を永続化する」といっても良いのでしょうか。そんな内容がアーカイブ(シリアライズ)です。
またアンアーカイブ(デシリアライズ)は、アーカイブされた変数の内容(バイナリーデータ)を、元の変数の形に 戻すことを言います(*´∇`*)
例えば、NSArrayをアーカイブする方法は以下のようになります。
アーカイブした結果は、NSData(バイナリーデータ)として受け取ります。
この内容を、CoreData, NSUserDefaults, FileSystemなど好きな場所に保存すれば、 データ永続化が出来ます。
以下のように実装することで、アーカイブした結果のNSDataから元のデータを復元できます。
アーカイブできるのは、NSCodingプロトコルを実装しているクラスです。
実装しているか否かは、書くクラスのクラスリファレンスで「Comforms to」部分を参照すると分かります。
例えば、上記例のNSArrayの他にも、UIView、NSString、UIImage、などの多くのクラスが NSCodingプロトコルを実装しています。
また独自に作成したクラスでもNSCodingを実装することで、アーカイブ可能となるようです。
例えば、UIViewを継承するUIWebViewをアーカイブした場合には、現在表示しているDOMの内容や JavaScriptの状態などはアーカイブされないようです。
アーカイブしようとしているクラスがどの程度の情報が永続化されるかは、実際に試してみる必要があります。
アーカイブやシリアライズに関する詳細は、以下をご参照ください。
Archives and Serialization Programming Guide
しかし上記の注意点でも書いたように、欲しい情報がアーカイブされず。。
結局、キャッシュ機能は自分で実装する事にしました(第3者が作成したものもありましたが)。
でもアーカイブ処理をしてNSDataとして受け取ることで、CoreDataに簡単に保存できるのは大きなメリットだなぁと 思いました。
今回も最後までお読み頂きましてありがとうございました(・∀・)
今日は、Objective-Cの色々な型(UIViewやNSArrayなど)をアーカイブして、状態をバイナリーデータとして 保存する方法と、そのデータをアンアーカイブして元の形に戻す方法をブログに書きたいと思います。
アーカイブ(シリアライズ)するとは?
アーカイブ処理とは、UIViewやNSArrayなどの型で保持するメモリ上の状態を、 バイナリーデータに変換して、データベースやファイルシステムに保存する事を言います。これを行うことで、現在の変数の状態をそのまま(型によっては一部情報が削除されますが)に、 次のアプリ起動時などに使うことが出来るようになります。
「変数の内容を永続化する」といっても良いのでしょうか。そんな内容がアーカイブ(シリアライズ)です。
またアンアーカイブ(デシリアライズ)は、アーカイブされた変数の内容(バイナリーデータ)を、元の変数の形に 戻すことを言います(*´∇`*)
Objective-Cでアーカイブする方法
Objective-Cでアーカイブする方法は簡単に1行で書く事ができます。例えば、NSArrayをアーカイブする方法は以下のようになります。
// アーカイブ対象のNSArrayを作成する。 NSArray *array = [NSArray arrayWithObjects:@"aaa", @"bbb", @"ccc", nil]; // アーカイブ処理を行う。 NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:array];NSKeyedArchiverクラスのメソッドを用いることで、アーカイブ処理を行うことが出来ます。
アーカイブした結果は、NSData(バイナリーデータ)として受け取ります。
この内容を、CoreData, NSUserDefaults, FileSystemなど好きな場所に保存すれば、 データ永続化が出来ます。
Objective-Cでアンアーカイブする方法
アンアーカイブする方法も簡単です。以下のように実装することで、アーカイブした結果のNSDataから元のデータを復元できます。
// アーカイブ処理を行う。 NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:array]; // アーカイブ結果から、元に戻す。 NSArray *unarchivedArray = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];NSKeyedUnarchiverを用いることで、簡単にアーカイブデータから元のデータを復元できます。
アーカイブできるクラスはどれ?
Objective-CやCocoaフレームワークで定義されているクラスの全てがアーカイブできる訳ではありません。アーカイブできるのは、NSCodingプロトコルを実装しているクラスです。
実装しているか否かは、書くクラスのクラスリファレンスで「Comforms to」部分を参照すると分かります。
例えば、上記例のNSArrayの他にも、UIView、NSString、UIImage、などの多くのクラスが NSCodingプロトコルを実装しています。
また独自に作成したクラスでもNSCodingを実装することで、アーカイブ可能となるようです。
アーカイブ時の注意点
NSCodingを実装しているからといって、変数の内容が全てアーカイブされない場合があります。例えば、UIViewを継承するUIWebViewをアーカイブした場合には、現在表示しているDOMの内容や JavaScriptの状態などはアーカイブされないようです。
アーカイブしようとしているクラスがどの程度の情報が永続化されるかは、実際に試してみる必要があります。
参考資料
今回は、以下のプログラミングガイドを参照しました。アーカイブやシリアライズに関する詳細は、以下をご参照ください。
Archives and Serialization Programming Guide
最後に
今回のアーカイブ処理を使い始めたのは、Web内容をアプリ内に完全にキャッシュしようと考えたのが発端でした。しかし上記の注意点でも書いたように、欲しい情報がアーカイブされず。。
結局、キャッシュ機能は自分で実装する事にしました(第3者が作成したものもありましたが)。
でもアーカイブ処理をしてNSDataとして受け取ることで、CoreDataに簡単に保存できるのは大きなメリットだなぁと 思いました。
今回も最後までお読み頂きましてありがとうございました(・∀・)