【iOS開発】Core Dataの基礎を学習
こんにちは
ビンゴ中西です。
弊社では凄腕エンジニアがCore Dataの難しい部分を
ある程度隠蔽して使えるようにしてくれていますので、
以下の手順を丸っと踏むことはないのですが、
今回はCore Dataの基礎を学びます。
1. プロジェクトを作成したらCoreData.frameworkを追加
何も考えずにCoraData.frameworkを追加しましょう。
とくにダウンロードすることもなくXcodeから普通にできます。
4. いよいよソースを実装しよう! その前に.....
おっしゃ!ソースが書けると思いきや、その前に、
NSManagedObjectを継承したUsersクラスを作成します。
NSManagedObject subclassを選んで、
Model.xcdatamodeldのUsersが選ばれるように作成します。
5. 今度こそソースを!
今度こそソースを書こうということで、
サルでもわかる Core Data 入門【概念編】 - A Day In The Life
を参考にさせていただきました。
ソースは下記などを参考に少し書き換えています。
iPhoneのディレクトリ - bi_naの日記
iphone - CoreData application directory crashes on iOS3 - Stack Overflow]
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // NSManagedObjectModel NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"]; NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; // NSPersistentStoreCoordinator NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel]; NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentPath = [searchPaths lastObject]; NSString *path = [documentPath stringByAppendingPathComponent:@"Hoge.sqlite"]; NSURL *storeURL = [NSURL fileURLWithPath:path]; [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:nil]; // NSManagedObjectContext NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; [context setPersistentStoreCoordinator:coordinator]; // context は NSManagedObjectContext クラスのインスタンス NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Users" inManagedObjectContext:context]; NSError *error = nil; if (![context save:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } }
5.1 ソースの説明
手順2で作ったファイル名を教えてやる。
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"]; NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
5.1.2 いやいやmomdってなによ?
momdってなんなでしょう?
Cocoaの日々: [iOS][Mac] CoreData - マイグレーション[4] モデルファイルの構成
こちらに詳しい説明がありました。
5.1.3 SQLiteファイルを作って教えてやる
6. データを登録したい!
サルでもわかる Core Data 入門【実装編】 - A Day In The Life
今度はこちらのソースをgithubからDownloadして直に読むことで、
以下の様に手を加えてみました。
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // NSManagedObjectModel NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"]; NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; // NSPersistentStoreCoordinator NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel]; NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentPath = [searchPaths lastObject]; NSString *path = [documentPath stringByAppendingPathComponent:@"Hoge.sqlite"]; NSURL *storeURL = [NSURL fileURLWithPath:path]; [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:nil]; // NSManagedObjectContext NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; [context setPersistentStoreCoordinator:coordinator]; // データ書き込み Users *u = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Users class]) inManagedObjectContext:context]; u.name = @"bingo"; u.age = @19; NSError *error = nil; if (![context save:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } }
7. データを取り出してみよう
[XCODE] CoreDataを用いてデータ管理を行う方法。検索編!!!! - YoheiM .NET
を参考にさせていただき、viewDidLoadを書き換えました。
なお、データは
name => bingo, age => 19
name => miya, age => 20
の2件を入れた状態を行っています。
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // NSManagedObjectModel NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"]; NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; // NSPersistentStoreCoordinator NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel]; NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentPath = [searchPaths lastObject]; NSString *path = [documentPath stringByAppendingPathComponent:@"Hoge.sqlite"]; NSURL *storeURL = [NSURL fileURLWithPath:path]; [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:nil]; // NSManagedObjectContext NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; [context setPersistentStoreCoordinator:coordinator]; // NSFetchRequestは、検索条件などを保持させるオブジェクトです。 // 後続処理では、このインスタンスに色々と検索条件を設定します。 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; // 検索対象のエンティティを指定します。 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Users" inManagedObjectContext:context]; [fetchRequest setEntity:entity]; // 一度に読み込むサイズを指定します。 [fetchRequest setFetchBatchSize:20]; // 検索結果を保持する順序を指定します。 // ここでは、keyというカラムの値の降順で保持するように指定しています。 NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:NO]; [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]]; // NSFetchedResultsControllerを作成します。 // 上記までで作成したFetchRequestを指定します。 NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil]; // データ検索を行います。 // 失敗した場合には、メソッドはfalseを返し、引数errorに値を詰めてくれます。 NSError *error = nil; if (![fetchedResultsController performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); } // 検索結果をコンソールに出力してみます。 // fetchedObjectsというメソッドで、検索結果一覧を配列で受け取れます。 NSArray *moArray = [fetchedResultsController fetchedObjects]; for (int i = 0; i < moArray.count; i++) { Users *u = [moArray objectAtIndex:i]; NSLog(@"name=%@, age=%@", u.name, u.age); } }
結果:
2012-12-07 18:58:50.796 coreDataSample[7829:11603] name=miya, age=20 2012-12-07 18:58:50.797 coreDataSample[7829:11603] name=bingo, age=19
取得できていました。
んー エンティティ名はUsersじゃなくてUserのが良さそうな予感....
アプリ制作実習 〜アクションバーアイコンをいじってみた〜
こんばんは、haneoです。
今回は製作中のアプリにアクションバーのアイコンをつけてみたので紹介します。
画面の上部についているこれです。
androidのバージョン3.0からつけられるようになったのですが、
今までアプリの持つ機能はメニューボタンを押して何が出来るのか探していたので
その画面で何が出来るか、アイコンで何となくわかるというのは便利ですね。
実装はonCreateOptionsMenu()というメソッドで
メニューのxmlファイルを呼んで、項目を作り
onOptionsItemSelected()というメソッドでそれぞれのボタンに機能を作って行く感じです
メニュー項目生成
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.album, menu); return true; }
画面を移動する機能をつけます。
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: Intent intent = new Intent(this, HomeActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; case R.id.menu_edit: Intent intentE = new Intent(this, AlbumEditActivity.class); startActivity(intentE); return true; case R.id.menu_add_new: Intent intentA = new Intent(this, PhotoNewActivity.class); startActivity(intentA); return true; default: return super.onOptionsItemSelected(item); } }
アイコンは結構種類があり、自分で作って足すことも可能なので直感的に
機能を表すアイコンを選びましょう。
好きな白黒画像からオリジナルのアイコンを作ってくれるツールもあるみたいですよ。