Persistence(6)~アーカイブへの保存(2)

2011. 02. 10
●ビューコントローラのヘッダファイルPersistenceViewController.hの編集

ビューコントローラのヘッダファイルでは、ユーザデータを保存するファイル名の変更と、アーカイブ用のキーの追加をします。
(太字が追加・修正した部分)

#import <UIKit/UIKit.h>

#define kFilename @"archive"
#define kDataKey @"Data"


@interface PersistenceViewController : UIViewController {
    UITextField *field1;
    UITextField *field2;
    UITextField *field3;
    UITextField *field4;
}

@property (nonatomic, retain) IBOutlet UITextField *field1;
@property (nonatomic, retain) IBOutlet UITextField *field2;
@property (nonatomic, retain) IBOutlet UITextField *field3;
@property (nonatomic, retain) IBOutlet UITextField *field4;

- (NSString *)dataFilePath;

@end

1209

ユーザデータを保存するアーカイブファイルの名前をarchiveと設定しています。

kDataKeyはユーザデータをアーカイブファイルにする、またはファイルからデータを取り出す際のキーとなります。


●ビューコントローラのソースファイルPersistenceViewController.mの編集

ソースファイルでは、アーカイブファイルを取り扱うためにFourLines.hのインポートの追加と、データの入出力を行っているapplicationWillResignActive:とviewDidLoadの改修を行います。
(太字が追加・修正した部分)

#import "PersistenceViewController.h"
#import "FourLines.h"

@implementation PersistenceViewController

@synthesize field1;
@synthesize field2;
@synthesize field3;
@synthesize field4;

- (NSString *)dataFilePath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:kFilename];
}

- (void)applicationWillResignActive:(UIApplication *)application {
    FourLines *fourLines = [[FourLines alloc] init];
    fourLines.field1 = field1.text;
    fourLines.field2 = field2.text;
    fourLines.field3 = field3.text;
    fourLines.field4 = field4.text;

    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:fourLines forKey:kDataKey];
    [archiver finishEncoding];
    [data writeToFile:[self dataFilePath] atomically:YES];
    [fourLines release];
    [archiver release];
    [data release];

}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *filePath = [self dataFilePath];

    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        FourLines *fourLines = [unarchiver decodeObjectForKey:kDataKey];
        [unarchiver finishDecoding];

        field1.text = fourLines.field1;
        field2.text = fourLines.field2;
        field3.text = fourLines.field3;
        field4.text = fourLines.field4;

        [unarchiver release];
        [data release];

    }

    UIApplication *app = [UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(applicationWillResignActive:)
        name:UIApplicationWillResignActiveNotification
        object:app];
}

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

    [super viewDidUnload];
    self.field1 = nil;
    self.field2 = nil;
    self.field3 = nil;
    self.field4 = nil;
}

- (void)dealloc {
    [field1 release];
    [field2 release];
    [field3 release];
    [field4 release];
    [super dealloc];
}

@end

1210

1)FourLines.hのインポートの追加

アーカイブファイルを扱うため、アーカイブ/アンアーカイブ処理を行っているFourLines.hをインポートします。

2)applicationWillResignActive:の編集

applicationWillResignActive:はアプリケーションが非アクティブになった時にファイルを出力するメソッドですので、中身を全て入れ替えています。

ここでは、ユーザデータであるテキストフィールドの文字列オブジェクトを取得し、キー付でエンコードしてバイト列に変換、そしてバイト列をファイルとして書き込む処理を行います。

最初にアーカイブ処理を行っているFourLinesクラスのインスタンスfourLinesを生成・初期化し、4つのテキストフィールドに入力されている文字列を代入します。

次にデータを入れるバイト列として、NSMutableDataのインスタンスを生成・初期化し、initForWritingWithMutableData:メソッドでキー付アーカイブをエンコードするための初期化を行います。

そしてencodeObject:forKey:メソッドで文字列の入ったfourLinesをエンコードし、finishEncodingでエンコードを完了します。

出来上がったバイト列は、writeToFile:atomically:メソッドでファイルarchiveに書き出します。


initForWritingWithMutableData:

- (id)initForWritingWithMutableData:(NSMutableData *)data

指定した可変データオブジェクトに、アーカイブをエンコードするための初期化をし、レシーバを返します。

戻り値はレシーバで、dataにアーカイブをエンコードするための初期化が行われています。

データのエンコードが終了した時、dataへの入力が完了した時点でfinishEncodingを呼び出す必要があります。

レシーバのフォーマットはNSPropertyListBinaryFormat_v1_0です。

data:アーカイブを書き込む可変データオブジェクトを指定します。


finishEncoding

- (void)finishEncoding

データストリームの最終的な構築をレシーバに指示します。

このメソッドを呼び出した後で、それ以上の値のエンコードを行うことはできません。

完了してからこのメソッドを呼び出す必要があります。


writeToFile:atomically:

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag

レシーバのバイト列を、指定したパスのファイルに書き込みます。

成功した場合はYESを、失敗した場合はNOを返します。

path:レシーバのバイト列を書き込むファイルパスを指定します。
ファイルパスにチルダ『~』が含まれる場合は、stringByExpandingTildeInPathメソッドで変換してください。

atomically:YESの場合、一度予備ファイルに書き出してから、本来指定したパスのファイルに書き換えます。
そのため、書き出し途中にクラッシュしても元のパスのファイル内容は保証されます。
NOの場合、直接指定したパスのファイルに書き出します。

3)viewDidLoadの編集

viewDidLoadでは、プロパティリストファイルからの読み込み部分を、アーカイブファイルからの読み込みに差し替えています。

まずinitWithContentsOfFile:メソッドでファイルを読み込み、バイト列であるNSDataオブジェクトとします。

次にそのバイト列をinitForReadingWithData:メソッドでデコードし、decodeObjectForKey:メソッドで元のFourLinesクラスのオブジェクトに復元し、finishDecodingでデコードを完了します。

後は復元されたFourLinesクラスのオブジェクトから文字列を取り出し、各テキストフィールドに設定します。


initForReadingWithData:

- (id)initForReadingWithData:(NSData *)data

事前にNSKeyedArchiverによってエンコードされたアーカイブをデコードしレシーバを初期化します。

戻り値は、dataをデコード化して初期化したNSKeyedUnarchiverオブジェクトです。

データのデコード化が完了したら、finishDecodingを呼び出す必要があります。

dataが有効なアーカイブでない場合、このメソッドはNSInvalidArchiveOperationExceptionを発生させます。

dataNSKeyedArchiverによって事前にエンコードされたアーカイブを指定します。


finishDecoding

- (void)finishDecoding

オブジェクトのデコード化が完了したことをレシーバに伝えます。

このメソッドを呼び出すと、レシーバはデリゲートに通知し、アーカイブの最終的な操作を実行します。

このメソッドを一度呼び出すと、レシーバはそれ以降値のデコードをすることができません。


●実行

ユーザデータを保存するファイルがプロパティリストからアーカイブファイルになるだけで、アプリケーションの動作は変わりません。

1211



参考文献

NSKeyedArchiver Class Reference

NSData Class Reference

NSKeyedUnarchiver Class Reference

はじめてのiPhone3プログラミングはじめてのiPhone3プログラミング
(2009/12/17)
Dave Mark、Jeff LaMarche 他

商品詳細を見る






Bose Solo 5 TV sound system
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
07 | 2017/08 | 09
Sun Mon Tue Wed Thu Fri Sat
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

ボーズ・オンラインストア
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR