MagicalRecord に mogenerator を組み合わせてよいか
CoreDataを使う際に、MagicalRecordに加えてmogeneratorを使う事を推奨しているブログ記事が散見されますが、mogeneratorには以下のようにリジェクトのリスクがあるようです。
Don't use mogenerator methods in place of standard Core Data calls #569
Referenced non-public APIs which caused AppStore rejection. #74
筆者はmogeneratorを使っていた事もありましたが、現在は別の理由もあってMagicalRecord単体で使っています。リジェクトのリスクはmogeneratorに限った話しではないですが、注意した方がいいかもしれません。
以上
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を簡単に扱えます。
OSXでDockerを使う
Dockerに特化した軽量Linuxのboot2dockerを使ってOSXでDockerを使ってみます。Dockerはv0.8でアーキテクチャを変更してOSXに対応し、homebrewにも入ったため誰でも簡単に使えるようになりました。
インストール
brew cask install virtualbox
brew cask install vagrant
brew install docker
brew install boot2docker
boot2dockerのVMを作成
boot2dockerのVirtualBox用のVMを作成します。
boot2docker init
※ boot2dockerは、Dockerコンテナを動かす目的に特化したTinyCoreLinuxベースの軽量Linuxディストリビューションです。
boot2dockerのVMを起動
boot2docker up
export DOCKER_HOST=tcp://localhost:XXXX
boot2dockerのVMへ接続(参考)
boot2docker ssh
ユーザ/パスワードは以下です。
user:docker
password:tcuser
コンテナイメージを探す
以下のサイトにDockerのコンテナがたくさんあります。
例1. Ubuntuのコンテナをダウンロード
Ubuntuのコンテナをダウンロードしてboot2dockerに展開します。
docker pull ubuntu
例1. Ubuntuへログイン
docker run -i -t ubuntu /bin/bash
例2. CentOSのコンテナをダウンロード
docker pull centos
例2. CentOSへログイン
docker run -i -t centos /bin/bash
トラブル対策
OSXとVirtualBox 4.3.8環境で問題が発生するケースがあります。
boot2docker / boot2docker - Kernel panic on VirtualBox 4.3.8 (Mac OS X) #260
現象
boot2docker up
に時間がかかるboot2docker ssh
で接続できない- Virtualbox内のvmがカーネルパニックを起こしている
- VBoxHeadlessが暴走している
解決策
上記現象が発生する場合は以下を実行します。
boot2docker stop
boot2docker delete
boot2docker init
VBoxManage setextradata boot2docker-vm VBoxInternal/CPUM/EnableHVP 1
boot2docker up
yeomanのangular-fullstackでMEAN (MongoDB + Express + AngularJS + Node.js)アプリをお手軽に開発
クライアントサイドのMV※フレームワークの一つにAngularJSがありますが、2012年にバージョン1.0がリリースされ、2013年になって一気に大流行しました。このAngularJSの流行に乗りながら、サーバサイドも含めてJavaScriptで開発するMEAN (MongoDB + Express + AngularJS + Node.js) 構成のスタイルにも注目が集まっています。
ここではyeomanの力を使って以下のような構成のMEAN+αアプリの雛形を簡単に生成してみます。
- yeoman
- yo
- bower
- grunt
- AngularJS
- node.js
- express
- passport
- jade
- sass
- Twitter Bootstrap 3
- MongoDB
- mongoose
- Karma
- CoffeeScript
今回はyeomanのgeneratorとして、全generator中第3位(MEANでは1位)のgithubスター数を獲得しているDaftMonk/generator-angular-fullstackを使用してみます。
前提条件
- node.js
- MongoDB
- compass (
gem install compass
)
インストール
yeomanのインストール
npm install -g yo
yeomanのangular-fullstackジェネレータのインストール
npm install -g generator-angular-fullstack
アプリ生成
angular-fullstackのアプリ雛形作成
mkdir [app name]
cd [app name]
yo angular-fullstack --jade
※--coffee
を付ければJavaScriptの代わりにCoffeeScriptが出力されます。
※angularとfullstackの間のハイフンが抜けていたので修正しました。
ウィザードでは、全てyesを選択しています。
アプリ起動
MongoDB起動
mongod
アプリ起動
grunt serve
ファイルを変更すると自動でリロードされます。
ディレクトリ構成
ディレクトリ構成はわかりやすく、app配下にはクライアントサイド(AngularJS)、lib配下にはサーバサイド(node.s + express)のリソースが格納されています。
. ├── Gruntfile.js ├── app : クライアントサイド (新規リソースはyo angular-fullstack:で生成) │ ├── bower_components │ ├── favicon.ico │ ├── images │ ├── robots.txt │ ├── scripts │ ├── styles │ └── views ├── bower.json ├── karma-e2e.conf.js ├── karma.conf.js ├── lib : サーバサイド (追加リソースは各自作成) │ ├── config │ ├── controllers │ ├── middleware.js │ ├── models │ └── routes.js ├── node_modules │ ├── bcrypt │ ├── connect-livereload │ ├── connect-mongo │ ├── express │ ├── grunt 略 │ ├── jade │ ├── jpegtran-bin │ ├── jshint-stylish │ ├── karma 略 │ ├── load-grunt-tasks │ ├── lodash │ ├── mongoose │ ├── mongoose-unique-validator │ ├── passport │ ├── passport-local │ ├── requirejs │ └── time-grunt ├── package.json ├── server.js : expressのメインファイルです └── test ├── runner.html └── spec
その他
今回は雛形作成までとして、今後より詳しい記事を書きたいと思いますが、幾つか必要な作業を書いておきます。
ページ(view)追加
新しいページ(view)を追加するには以下のコマンドを実行します。クライアントサイドのcontroller, route, viewがまとめて自動生成されます。
yo angular-fullstack:route [view名=route名]
注意
はじめに
--jade
や--coffee
を付けておくと、以降その設定は引き継がれ毎回指定しなくてもjadeやCoffeeScriptのファイルが生成されます。directive等も同様に生成できます。
ユーザ登録
初期状態だとユーザ登録してもMongoDBにユーザが登録されません。アプリを再起動する度にユーザを削除してテストユーザを作成しているためです。これを解除する為にはserver.jsからdummydata.jsを読み込んでいる部分を変更します。
Hacker Newsの記事をMongoDBに蓄積するPythonアプリケーションをGIthubとHerokuで公開
Hacker NewsのエントリをMongoDBに蓄積するWebアプリをGitHubとherokuに公開しました。目的はHacker Newsのエントリの分析で今後そうした機能を公開するかもしれません。MIT Licenseなので好きに使ってください。