Persistence(4)~プロパティリストへの保存(2)

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

ソースファイルでは、アウトレットのプロパティとプロパティリストへのファイルパスを生成するメソッド、アプリケーション非アクティブ時に呼び出されるメソッドの実装、そしてビューを表示するviewDidLoadメソッドの変更を行います。
(太字が追加・変更した部分)

#import "PersistenceViewController.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 {
    NSMutableArray *array = [[NSMutableArray alloc] init];
    [array addObject:field1.text];
    [array addObject:field2.text];
    [array addObject:field3.text];
    [array addObject:field4.text];
    [array writeToFile:[self dataFilePath] atomically:YES];
    [array 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]) {
        NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
        field1.text = [array objectAtIndex:0];
        field2.text = [array objectAtIndex:1];
        field3.text = [array objectAtIndex:2];
        field4.text = [array objectAtIndex:3];
        [array 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

1204

1)プロパティの実装

ヘッダファイルで宣言した4つのテキストフィールドのプロパティを実装します。

2)dataFilePathの実装

ユーザデータを保持するプロパティリストのファイルパスを取得し、文字列として返します。

データの保存先は、ユーザアプリケーションディレクトリ下のDocumentsディレクトリになり、ここへのファイルパスは『Persistence(2)~ディレクトリパスの入手』で紹介した方法と同じです。

ディレクトリパスを検索するNSSearchPathForDirectoriesInDomainsメソッドを使用し、第一引数をドキュメントディレクトリを指すNSDocumentDirectoryに、第二引数の検索範囲はアプリケーションのホームディレクトリとなるNSUserDomainMaskに、第三引数は、YESにします。

objectAtIndex:で得たドキュメントディレクトリのパスに、stringByAppendingPathComponent:でファイル名を追加して文字列を返します。

3)applicationWillResignActive:の実装

applicationWillResignActive:は、アプリケーションが非アクティブになったことを知らせる通知UIApplicationWillResignActiveNotificationを受信すると呼び出されるメソッドで、ここではテキストフィールドに入力されている文字列を取得して配列とし、プロパティリストファイルに出力する処理を行っています。

テキストフィールドに入力されている文字列をtextプロパティで取得し、addObject:メソッドで可変配列arrayに追加していき、writeToFile:atomically:でファイルに出力します。


writeToFile:atomically:

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

指定したパスにあるファイルに配列の内容を書き込みます。

戻り値は、ファイルの書き込みに成功した場合はYES、それ以外の場合はNOを返します。

配列の内容が全てプロパティリストオブジェクト(NSString、NSData、NSArray、NSDictionaryオブジェクト)の場合、このメソッドによって書き込まれるファイルは、クラスメソッドarrayWithContentsOfFile:またはインスタンスメソッドinitWithContentsOfFile:で使用することができます。

このメソッドはファイルに書き込む前に、含まれている全てのオブジェクトがプロパティリストのオブジェクトであるかを再帰的に検証し、プロパティリストオブジェクトでない場合はNOを返し、その結果有効なプロパティリストではなくなります。

path:配列の内容を書き込みするパスを指定します。
pathにチルダ『~』が含まれている場合は、このメソッドを呼び出す前にstringByExpandingTildeInPathで展開する必要があります。

flag:YESの場合、配列は一旦補助ファイルに書き込まれ、その後補助ファイルはのパス名を書き換えます。
NOの場合、配列は直接パスのファイルに書き込まれます。
YESオプションはpathのファイルを保証し、ファイルの書き込み中にシステムがクラッシュしても、pathのファイルは破壊されません。

4)不要なメソッド

initWithNibName:bundle:loadViewメソッドは今回使用しないので削除します。

5)viewDidLoadの編集

viewDidLoadでは、ユーザデータのプロパティリストファイルが存在する場合にファイルを読み込んでテキストフィールドに反映させる処理と、アプリケーションが非アクティブになったことを知らせる通知UIApplicationWillResignActiveNotificationが発行されたらapplicationWillResignActive:を呼び出す設定を行っています。

コメントアウトを解除し、スーパークラスによる初期化は最初に行います。

次にdataFilePathメソッドを呼び出しユーザデータのプロパティリストファイルのパスを取得します。

ファイルの有無を確認するため、defaultManagerメソッドでファイルマネージャのインスタンスを取得し、fileExistsAtPath:メソッドで判定します。

ファイルが存在する場合は、initWithContentsOfFile:でファイルから配列を生成し、objectAtIndex:メソッドでテキストフィールドに文字列を設定します。

(ファイルの有無に関わらず)判定後に通知の処理を行います。

まずsharedApplicationメソッドでアプリケーションのインスタンスを取得します。

その後通知を得るためにデフォルトの通知センターをdefaultCenterメソッドで取得します。

最後にaddObserver:selector:name:object:メソッドで、通知に対する処理を行います。

第一引数はselfなのでPersistenceViewControllerが通知に関する監視を行います。

第二引数は通知を受け取った場合の処理として、applicationWillResignActive:の呼び出しを指定しています。

第三引数は対象とする通知で、アプリケーションの非アクティブを検知するUIApplicationWillResignActiveNotificationを指定します。

第四引数は通知を発するオブジェクトを制限するもので、ここでは当アプリケーションが発する通知のみを有効としています。


defaultManager

+ (NSFileManager *)defaultManager

ファイルシステムのデフォルトNSFileManagerオブジェクトを返します。

常にファイルマネージャの同じインスタンスを返します。

このオブジェクトはスレッドセーフではありません。


fileExistsAtPath:

- (BOOL)fileExistsAtPath:(NSString *)path

指定したパスのファイルまたはディレクトリが存在するかどうかを示すブール値を返します。

戻り値は、pathで指定したファイルが存在する場合はYES、そうでない場合はNOを返します。

指定したpathの最後の要素がシンボリックリンクの場合、このメソッドはリンクを横断し、リンク先にファイルが存在するかどうかを元にYESかNOかを返します。

ファイルシステムの現在の状態やファイルシステム上の個々のファイルを元に、断定した動作を試みることは推奨しません。

実行すると、ファイルシステムが競合状態の場合に異常動作が発生する可能性があります。

(ファイルの読み込みやディレクトリの生成などの)操作を試すよりも、操作が成功するかどうかを事前に把握しようと試して、エラー処理やエラーのチェックをする方が遥かに良いです。

ファイルシステムの競合状態に関する詳細は、『Secure Coding Guide』の『Race Conditions and Secure File Operations』を参照してください。

path:ディレクトリやファイルのパスを指定します。
pathがチルダ『~』で始まる場合は、最初にstringByExpandingTildeInPathで展開するか、このメソッドでNOを返す必要があります。


initWithContentsOfFile:

- (id)initWithContentsOfFile:(NSString *)aPath

指定したパスのファイルに含まれている内容で、新規に割り当てられた配列を初期化します。

戻り値は、aPathで指定されたファイルの内容で初期化された配列で、ファイルが開けないまたはファイルの内容で配列が解釈できなかった場合はnilを返します。

返されるオブジェクトは、元のレシーバのものと異なる場合があります。

aPathで識別されるファイルで表現される配列はプロパティリストオブジェクト(NSString、NSData、NSArray、NSDictionaryオブジェクト)のみを含んでいる必要があります。

元の配列が可変であっても、この配列に含まれるオブジェクトは不変になります。

aPathwriteToFile:atomically:メソッドによって生成される配列で表される文字列を含むファイルへのパスを指定します。


sharedApplication

+ (UIApplication *)sharedApplication

シングルトンのアプリケーションインスタンスを返します。

アプリケーションインスタンスはUIApplicationMain関数で生成されます。


defaultCenter

+ (id)defaultCenter

タスクのデフォルトの通知センターを返します。

戻り値は現在のタスクのデフォルトの通知センターで、システムの通知に使用されます。


addObserver:selector:name:object:

- (void)addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender

レシーバのディスパッチテーブルに、オブザーバと通知セレクタ、オプションの基準として通知名とセンダーを追加登録します。

addObserver:selector:name:object:で指定したnotificationObserverやその他のオブジェクトは、removeObserver:またはremoveObserver:name:object:を呼び出す前に解放してください。

notificationObserver:オブザーバとして登録するオブジェクト。
この値はnilにしないでください。

notificationSelector:セレクタは、レシーバがnotificationObserverに通知を送信するための、メッセージを指定します。
メソッドはnotificationSelectorで(NSNotificationのインスタンスの)引数を一つだけ指定する必要があります。

notificationName:登録するオブザーバ用に、通知の名前を指定します。
つまり、この名前の通知のみオブザーバに配信されます。
nilを渡した場合、通知センターはオブザーバへの配信に通知名を使用しません。

notificationSender:オブザーバに通知を受信させたいオブジェクトを指定します。
このセンダーの送信する通知のみ、オブザーバに配信されます。
nilを渡した場合、通知センターはオブザーバへの配信にセンダーを使用しません。

6)shouldAutorotateToInterfaceOrientation:の実装

サンプルコードでは触れられていませんが、shouldAutorotateToInterfaceOrientation:のコメントアウトを解除してデフォルトの状態(ポートレートのみ有効)で実装しています。

7)viewDidUnloadの実装

旧版の本書ではviewDidUnloadは記述されていませんが、サンプルコードにもあるように4つのプロパティの所有権放棄を行います。

スーパークラスによる初期化は、最初に行っています。

8)deallocの実装

deallocでは本書やサンプルコードと同じく、4つのプロパティの解放を行っています。



参考文献

UIApplication Class Reference

UIApplicationDelegate Protocol Reference

NSArray Class Reference

NSFileManager Class Reference

NSNotificationCenter Class Reference

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

商品詳細を見る

Beginning Ios 6 Development: Exploring the Ios SdkBeginning Ios 6 Development: Exploring the Ios Sdk
(2012/12/26)
David Mark、Jack Nutting 他

商品詳細を見る






5.1chホームシアターシステム
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

5.1chホームシアターシステム
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