【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のが良さそうな予感....