このチュートリアルでは、各種データをNSUserDefaultsを使って、保存、抽出する方法について説明します。
NSUserDefaults は、データベースの知識を必要としないので、SQLite3のようなデータベースを必要としない(ゲームのハイスコア、ログイン情報、アプリの設定など)、小規模のデータを扱う場合には便利で簡単です。
今回は、例として、初回時にアプリを起動し、名前を入力すると、保存され、次回以降の起動時には、保存された名前が自動的に名前が表示されるアプリケーションを作成します。
目次
View Based Application を作成
特別な機能(TabBar、テーブルなど)を必要としないアプリケーションの場合は、これで十分です。
XCode を起動し、View Based Application を作成します。保存する名前はなんでも構いませんが、今回は、「AppPrefSample」とします。
IBOutles と IBAction を設定
作成されたプロジェクト内から、「AppPrefSampleViewController.h」を開き、IBOutlets & IBActions を設定します。
#import <UIKit/UIKit.h>
@interface AppPrefSampleViewController : UIViewController {
IBOutlet UITextField *name;
IBOutlet UILabel *greeting;
}
@property(nonatomic,retain) IBOutlet UITextField *name;
@property(nonatomic,retain) IBOutlet UILabel *greeting;
-(IBAction) updatePrefs:(id) sender;
@end
IBOutlet を UILabel や UITextField に設定し、インターフェースとコードを結びつけます。updatePrefs というIBAction を設定し、インターフェースに設置したUIButton と接続します。ユーザがボタンを押すと、このメソッドが呼ばれ、データが保存されます。
Interface Builder でインターフェースを作成
今回のチュートリアルで作成するインターフェースは非常に単純です。UILabel, UIButton, そして UITextField を利用するので、それぞれ、ライブラリからview の上にドラッグするだけです。
xib(nibファイル)をダブルクリックして、Interface Builder を起動します。
起動したら、view 上に、UILabel、UITextField、UIButtonを配置します。以下の画像を参照してください。
設置したUI Components と Outlets&Action を接続
単純に、UIComponents とコードを接続します。
もし、インターフェースとコードを接続することがよく分からなければ、以前の記事「[3]:Interface Builder と Xcode を接続する方法」をご確認ください。
UILabel、UITextField のConnection Inspector から、New Referenceing Outlet の右の○をドラッグし、File’s Owner に結びつけ、それぞれ greeting,nameと接続します。
さらに、UITextField のConnections Inspector 内の Events から Did End On Exit の右の○をFile’s Owner にドラッグし、updatePrefs を選択します。同様に、UIButton の Events 内の Touch Up Inside からFile’s Owner に接続し、updatePrefsを選択します。これで保存し、Interface Builder を終了します。
UpdatePrefs Method を実装します。
「AppPrefSampleViewController.m」を開き、以下のように編集します。
#import “AppPrefSampleViewController.h”
@implementation AppPrefSampleViewController
@synthesize name,greeting;
-(IBAction) updatePrefs:(id) sender{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:name forKey:@”greeting”];
[name resignFirstResponder];
greeting.text = @”設定が保存されました!“;
}
このメソッドにより、NSUserDefaults が保存されるように設定します。このメソッドは、以下のように動作します。
- NSUserDefaults object への参照を取得します – データを保存するために、このオブジェクト上で、メソッドを実行します。
- setObject forKey メソッドを呼び出します – 与えられた key に文字列を保存します。 key は、データの保存先を特定するために使う文字列の値です。
- ボタン(return)が押された時に、UITextField 上のキーボードが隠れるように resignFirstResponder メソッドを呼びます。
- データが保存されたことをユーザに伝えるために「アプリケーションに保存されました」とラベルの文字列を更新します。
ViewDidLoad Method を実装します。
– (void)viewDidLoad {
[super viewDidLoad];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *greetName = [prefs stringForKey:@”greeting”];
if(greetName == nil){
greeting.text = @”Welcome Guest!”;
}else {
greeting.text = [[NSString alloc] initWithFormat:@”Welcome %@!”,greetName];
}
}
このメソッドは、viewがロードされた時に呼ばれるメソッドです。このメソッドで行うことは、保存されたNSUserDefault を @”greeting” というキーを使って呼び出します。これにより、ユーザが保存した名前を取り出します。もし、この変数が nil であれば、アプリケーションが初めて起動されたか、ユーザが一度も、保存ボタンを押していないか、のどちらかです。以下、メソッドの説明です。
- NSUserDefaults object へのハンドルを取得します。
- @”greeting” というキーを、getObject メソッドに渡し、保存されたユーザ名を取得します。
- 保存されているユーザ名が nil かどうかを確認します。もし、nil であれば、設定されたデフォルトメッセージが表示されます。
- nil でなければ、initWithFormat のコンストラクタを使って、新しい文字列を生成します。これにより、Welcome メッセージにユーザ名を添えます。initWithFormat は、1つ以上の引数をとります。最初は、文字列のフォーマット、今回の場合は、 「@”Welcome %@!”」です。“%@”の箇所は、後で指定する文字列に置き換えます。
- この名前の文字列が生成されると、name.text に当てはめて、ラベルを更新します。
これで完成です。ビルド&実行してみてください。
iOS4のシミュレータだと、正常に動作したり、しなかったり、不安定というか、動作に一貫性がない感じだったので、iOS3のシミュレータで実行してみました。
実機では、正常に動作していました。
調べてみると。。。
//データをファイルへ反映
[prefs synchronize];データファイルへの反影、シンクロされるタイミングをしっかりすることで無事解決しました。
これ忘れると、お任せのタイミングになっちゃうので意図した動作をしない可能性があります。(http://ameblo.jp/iphone0126/entry-10696992738.html)ということらしいです。なので、「greeting.text = @”設定が保存されました!“;」の前後あたりに、[prefs synchronize]; をすれば、解決すると思われます。
NSUserDefault によって、出来ること
以下は、NSUserDefault によって、出来ることのクイックリファレンスです。
保存する
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSString
[prefs setObject:@”TextToSave” forKey:@”keyToLookupString”];
// saving an NSInteger
[prefs setInteger:42 forKey:@”integerKey”];
// saving a Double
[prefs setDouble:3.1415 forKey:@”doubleKey”];
// saving a Float
[prefs setFloat:1.2345678 forKey:@”floatKey”];
// This is suggested to synch prefs, but is not needed (I didn’t put it in my tut)
[prefs synchronize];
取り出す
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *myString = [prefs stringForKey:@”keyToLookupString”];
// getting an NSInteger
NSInteger myInt = [prefs integerForKey:@”integerKey”];
// getting an Float
float myFloat = [prefs floatForKey:@”floatKey”];