MagicalRecordでCoreDataをお手軽に使う
iOSアプリでデータを保存(serialize/deserialize)する方法としてCoreDataがありますが、コード量が多く慣れるまでにも時間がかかります。
ここではより簡単なMagicalRecordによって、CoreDataを使ってみます。
MagicalRecordはActive Recordパターンを採用したCoreDataのラッパーです。ActiveRecordは、Martin FowlerらのPatterns of Enterprise Application Architectureで名付けられ、Ruby on Railsで普及しました。
MagicalRecordがあれば、Webアプリ開発者でもCoreDataを簡単に扱えるようになり、iOSアプリ開発がより身近に感じられるようになると思います。
前提
CocoaPodsはインストール済みとします。CocoaPodsのインストール方法は以下を参照してください。
iOSアプリのプロジェクト作成
Xcodeを開いて新規プロジェクトを作成します。
File > New > Project
- Use Core Dataの指定は不要です。
- 指定すると不要なコードが生成されるため、指定しない事をおすすめします。
- Use Core Dataの指定は不要です。
MagicalRecordのインストール
Podfile作成
.xcodeproj
があるディレクトリにPodfile
ファイルを作成します。Podfile
に次の1行を追記します。pod 'MagicalRecord'
MagicalRecordインストール
ターミナル上で
Podfile
と同じディレクトリに移動して以下を実行します。pod install
設定
アプリ名/アプリ名-Prefix.pch
を開いて次の1行を追記します。#import "CoreData+MagicalRecord.h"
CoreDataデータモデルの定義と作成
Data Modelを追加
- メニューから
File > New > File > Data Model
を選択します。 Model.xcdatamodeld
を作成します。
- メニューから
Entityを追加
- ツリー上で
Model.xcdatamodeld
を選択します。 Add Entity
をクリックしてEntityを追加します。- Entityを適切な名前に変更します。
- Entityの属性(Attributes)や関係(Relationship)を定義します。
- ツリー上で
Entityから必要なソースコードを自動生成
- ツリー上で
Model.xcdatamodeld
を選択します。 メニューから
Editor > Create NSManagedObject Subclass > Next > Next > Create
を選択します。※
Use scalar properties for priitive data types
をチェックすると以下のようなスカラー型(定数型)のプロパティがプリミティブなデータ型に変換されます。チェック不要で構いません。- Date -> NSTimeInterval.
- Double -> double.
- Float -> float.
- Integer 16/32/64 -> int16_t/int32_t/int64_t
- Boolean -> BOOL
- ツリー上で
MagicalRecordの起動/終了処理
起動処理
AppDelegete.m
ファイルを開いてdidFinishLaunchingWithOptionsに起動処理を追加します。- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 以下を追加 [MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"database_name.sqlite"]; return YES; }
初期化には以下のようなメソッドが用意されています。目的に応じて選択します。
ローカルのSQLite用
+ (void) setupCoreDataStack; + (void) setupAutoMigratingCoreDataStack; + (void) setupCoreDataStackWithInMemoryStore; + (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName; + (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName;
+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore; + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent; + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion;
終了処理
AppDelegete.m
ファイルを開いてapplicationWillTerminate
に終了処理を追加します。- (void)applicationWillTerminate:(UIApplication *)application { // 以下を追加 [MagicalRecord cleanUp]; }
MagicalRecordでのデータ保存
同期
Album *album = [Album MR_createEntity]; album.title = @"Friends"; : [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
※MR_save
メソッドは次期メジャーリリースの3.0からは無くなるので同じ機能を持つMR_saveToPersistentStoreAndWait
を使いましょう。
非同期
Album *album = [Album MR_createEntity]; [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){ //保存前の処理(保存したいインスタンスの作成など) Album *localAlbum = [album MR_inContext:localContext]; localAlbum.title = @"NeverMind"; : } completion:^(BOOL success, NSError *error) { //保存後の処理(全件取得や件数カウントなど) }];
その他
MagicalRecordでのデータ取得
全件取得
NSArray *albums = [Album findAll];
条件を指定して取得
NSArray *albums = [Album MR_findByAttribute:@"genre" withValue:@"piano trio" andOrderBy:@"year" ascending:YES];
その他高度な取得
MagicalRecordでのデータ更新
データ取得&更新
あらかじめAlbumのインスタンス(ここではcheckyourhead)を取得しておきます。
Album *checkyourhead = ...; checkyourhead.rate = [NSNumber numberWithInt:5]; [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
MagicalRecordでのデータ削除
全件削除
[Album MR_truncateAll]; [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
1件削除
あらかじめAlbumのインスタンス(ここではmellowgold)を取得しておきます。
Album *mellowgold = ...; [mellowgold MR_deleteEntity];
MagicalRecordでのデータカウント
カウント
NSNumber *count = [Album MR_numberOfEntities];
注意
MagicalRecordでデータの保存、更新、削除を反映する際は必ず以下を実行します。
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
以上です。MagicalRecordを使うとCoreDataを簡単に扱えます。