プロジェクトを作った後にCoreDataを追加する方法
普通はアプリを作成する際にCoreDataを使うにチェックを入れておくけど、チェックを入れてなかったプロジェクトに後でCoreDataを追加したい手順を書いておく。
1. Data Model追加
- Xcodeのメニューから File > New > New File... を選択。
- テンプレート選択ウインドウで iOS > Core Data > Data Model を選択。
- xcdatamodelファイルを保存
2. Entity追加
- 追加されたxcdatamodelファイルを選択。
- Add EntityをクリックしてEntityを追加
- 追加したEntityにAttibutesを追加、定義
- 作成したEntityを選択して、Editor -> CreateNSManagedObjectSubClassでEntityに対応したソースを作成する
3. データファイル保存用のDirectoryを作成
SQLiteの場合データファイル配置用のディレクトリがないとエラーになるのでディレクトリを作成しておく デフォルトは/Users/AirMyac/Library/Application Support/${HOGE}
※最初からCoreData作っても必要だと思う配布するなら起動時とかに作っとかないといけないから適当なコードで作成するようにしておく
こんな感じ?
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
NSError *error = nil;
if(![[NSFileManager defaultManager] createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error]){
NSLog(@"Couldn't create the data store directory.[%@, %@]", error, [error userInfo]);
abort();
}
}
4. AppDelegate.hに必要なソースを追記
自動生成される必要なソースを追記する。
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
5. AppDelegate.mにも必要なソースを追記
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize managedObjectContext = _managedObjectContext;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
// 初回起動用にDataStore用のDirectoryを作成する
NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
NSError *error = nil;
if(![[NSFileManager defaultManager] createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error]){
NSLog(@"Couldn't create the data store directory.[%@, %@]", error, [error userInfo]);
abort();
}
}
// Returns the directory the application uses to store the Core Data store file. This code uses a directory named hoge" in the user's Application Support directory.
- (NSURL *)applicationFilesDirectory
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *appSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];
return [appSupportURL URLByAppendingPathComponent:@"Hoge"];
}
// Creates if necessary and returns the managed object model for the application.
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
// Returns the persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.)
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator) {
return _persistentStoreCoordinator;
}
NSManagedObjectModel *mom = [self managedObjectModel];
if (!mom) {
NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));
return nil;
}
NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
NSError *error = nil;
NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"hoge.sqlite"];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
_persistentStoreCoordinator = coordinator;
return _persistentStoreCoordinator;
}
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey];
[dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey];
NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
[[NSApplication sharedApplication] presentError:error];
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
// Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application.
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window
{
return [[self managedObjectContext] undoManager];
}
// Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user.
- (IBAction)saveAction:(id)sender
{
NSError *error = nil;
if (![[self managedObjectContext] commitEditing]) {
NSLog(@"%@:%@ unable to commit editing before saving", [self class], NSStringFromSelector(_cmd));
}
if (![[self managedObjectContext] save:&error]) {
[[NSApplication sharedApplication] presentError:error];
}
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
// Save changes in the application's managed object context before the application terminates.
if (!_managedObjectContext) {
return NSTerminateNow;
}
if (![[self managedObjectContext] commitEditing]) {
NSLog(@"%@:%@ unable to commit editing to terminate", [self class], NSStringFromSelector(_cmd));
return NSTerminateCancel;
}
if (![[self managedObjectContext] hasChanges]) {
return NSTerminateNow;
}
NSError *error = nil;
if (![[self managedObjectContext] save:&error]) {
// Customize this code block to include application-specific recovery steps.
BOOL result = [sender presentError:error];
if (result) {
return NSTerminateCancel;
}
NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message");
NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info");
NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title");
NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title");
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:question];
[alert setInformativeText:info];
[alert addButtonWithTitle:quitButton];
[alert addButtonWithTitle:cancelButton];
NSInteger answer = [alert runModal];
if (answer == NSAlertAlternateReturn) {
return NSTerminateCancel;
}
}
return NSTerminateNow;
}
}