コンソールアプリでCoreDataを使う

はじめに

最近何を思ったかObjective-Cを勉強しています。
初めはとっても取っ付きづらい言語だと思いましたが、
今ではそこまで拒絶反応を示すこと無く取り組めています。
何事も慣れだと思いましたねぇ^^;

さてこの記事、とてもニッチなタイトルですが、Objective-C
というよりもiOSMac OSでデータ管理をするのに便利なCoreDataという技術を
「どうすればコンソールアプリケーションで利用できるか」をご紹介します。

CoreDataで検索をするとiOSMac OSプログラミングの記事はたくさん出てくるのですが、
コンソールアプリケーションからCoreDataを叩くものは無かったように思えるので
自分で利用するメモがてら、つらつらと書いていこうと思います。

CoreDataを利用する

早速ネタバレしてしまうと、Xcodeの新規作成ウィザードでCoreDataを利用する
コンソールアプリケーションのテンプレートが作成できます。何事も解決ですねw

プロジェクトの新規作成画面で、
[OS X] -> [Application] -> [Command Line Tool] を選び Next をクリックし、
いつものプロジェクトの名前を入れる画面の下部にある Type のリストボックスから
[Core Data]を選択してプロジェクトを作成するとあっという間にできます。んー。

せっかくなので

これで終わりなのもしゃくなので、CoreDataを利用するために必要な
NSManagedObjectContextを管理するクラスを作成し、コンテキストを取得できるようにしましょう。
以下のようなクラスを作ると、開発がスムーズになる、かもしれません。

CoreDataManager.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface CoreDataManager : NSObject
+ (NSManagedObjectContext *)getManagedObjectContext;
+ (NSManagedObjectModel *)  getManagedObjectModel;
@end
CoreDataManager.m
#import "CoreDataManager.h"

// 静的変数でコンテキストを保持
static NSManagedObjectContext *managedObjectContext = nil;
static NSManagedObjectModel   *managedObjectModel = nil;

@implementation CoreDataManager
+ (NSManagedObjectContext *)getManagedObjectContext {
    if(managedObjectContext != nil) {
        return managedObjectContext;
    }
    
    @autoreleasepool {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        
        NSPersistentStoreCoordinator *coordinator =
        [[NSPersistentStoreCoordinator alloc]
         initWithManagedObjectModel: [self getManagedObjectModel]];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
        
        NSString *STORE_TYPE = NSSQLiteStoreType;
        
        NSString *path = [[NSProcessInfo processInfo] arguments][0];
        path = [path stringByDeletingPathExtension];
        NSURL *url = [NSURL fileURLWithPath: [path stringByAppendingPathExtension: @"sqlite"]];
        
        NSError *error;
        NSPersistentStore *newStore =
        [coordinator addPersistentStoreWithType: STORE_TYPE
                                  configuration: nil
                                            URL: url
                                        options: nil
                                          error: &error];
        
        if(newStore == nil) {
            NSLog(@"Store Configuration Failure");
            return NO;
        }
    }
    
    return managedObjectContext;
}

+ (NSManagedObjectModel *)getManagedObjectModel {
    if(managedObjectModel != nil) {
        return managedObjectModel;
    }

    // ApplicationName はプロジェクトに合わせて
    NSString *path = @"ApplicationName";
    path = [path stringByDeletingPathExtension];
    NSURL *modelUrl =
    [NSURL fileURLWithPath: [path stringByAppendingPathExtension: @"momd"]];
    managedObjectModel = [[NSManagedObjectModel alloc]
                          initWithContentsOfURL: modelUrl];
    
    return managedObjectModel;
}
@end

ほとんどテンプレート通りで申し訳ないです…。

CoreDataManagerクラスのクラスメソッドから、初期化されたコンテキストを
取得することによって様々なクラスからCoreDataの機能を利用することが可能になります。

あとはプロジェクトにData Model(ApplicationName.xcdatamodeld)を追加して
モデルを設計するといい感じです。

最後に

CoreDataはとにかくsqliteファイルを作らなければなりません。
それを今回作成したCoreDataManagerクラスで管理しています。
コンソールアプリケーションの場合、そのファイルの作成を手動でやらなければならないので
iOSMac OSアプリケーションとは違って少し手間がかかりますが、それを乗り切ればあとは楽勝です。
CoreDataをコンソールアプリケーションでも便利に使って行きましょう。