Jan 292012
 

Xcode4でCoreDataを使ってUnitTests(Logic)を行う場合の設定方法。新規プロジェクト生成でUnitTestsをする設定にチェックを入れた場合のDefaultはUnitTests(Application)となる。つまり、UnitTests(Logic)は開発者が新規設定が必要となる。

UnitTestsのタイプ

  • Application Test(UIViewなどを含めた全体テスト)
  • Logic Test(UI以外のデータのテスト)
アプリケーション(以下アプリ本体)のidentifierは(com.f60k.Hergo)という仮想アプリで説明する。

Logic Testの作成Howto

Testing Bundleを新規作成。Add Targetボタンを押すとダイアログが出現する。名前はアプリ本体の名前にLogicTestsを追記したものにした。指定したProductName(com.f60k.HergoLogicTests)は後で使うので覚えておく。追加されるとフォルダが作成される。

CoreDataの3つの重要ポイント(Logic Testの場合)

  • xcdatamodelはコンパイルに含める(モデルの設定)
  • NSBundleはidentifierから設定(モデルの設定)
  • NSStoreTypeはInMemoryに設定(永続ストアの設定)
xcdatamodelはコンパイルに含める
NSManagedObjectModelを作成するときには(.mom)ファイルが必要。コンパイルに含めた(.xcdatamodelファイル)から生成される。アプリ本体では自動的に追加されるが、Logic Testでは開発者が追加しなければならない。
NSBundleはidentifierから設定
開発マシンにはどこかに以下のように.momファイルが保存されている。これが実際のbundle(com.f60k.HergoLogicTests)の中身である。正しく生成され保存されているのがわかる。
bundleが存在するのは分かった。このbundleの位置(path)からmodelを取り出す。[NSBundle mainBundle]の指す位置はLogic Testでは取得できない。
mainBundleから取り出せたbundleのidentifierは
  • アプリ本体→com.f60k.Hergo
  • Application Test→com.f60k.Hergo
  • Logic Test→null(com.f60k.HergoLogicTestsとなれば問題ないが…)
Logic Testで正しく取り出すには以下のように開発者がハードコードで指定して取得する。(ハードコードの問題点は後半。)
[NSBundle bundleWithIdentifier:@"com.f60k.HergoLogicTests"];
 これによりidentifierが正しく特定され、bundleの保存されている場所(path)を探し出すことが出来る。
NSStoreTypeはInMemoryに設定
  • NSSQLiteStoreType
  • NSInMemoryStoreType

その他重要ポイント(Testに関係なく一般的に行うこと)

  • CoreDataのフレームワークをビルド設定に追加する
  • prefixヘッダにCoreDataを追加する
CoreDataのフレームワークをビルド設定に追加する
prefixヘッダにCoreDataを追加する
LogicTestsのSupporting Filesのpchファイルの中にCoreData.hを追記する。
#import <CoreData/CoreData.h>

Application TestではApplicationにターゲット依存しているため、通常のアプリ開発と同じ手順で問題ない。

ハードコードの問題点

Logic Testの設定をハードコードすると書き換えでミスをする可能性がある。自動で設定が切り替わるようにしておくと便利である。

自動切り替え設定のポイント

  • スキーマに環境変数を設定する
  • 環境変数の値を設定値の分岐に利用する
スキーマに環境変数を設定する
環境変数の値を設定値の分岐に利用する
getenv()を使って設定した変数を取り出せば、通常はSQLでLogic TestではInMemoryと使い分けが出来る。
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Hergo.sqlite"];
NSString *storeType = NSSQLiteStoreType;
#if DEBUG
if (getenv("logicTests"))
{
storeType = NSInMemoryStoreType;
storeURL = nil;
}
#endif
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:storeType configuration:nil URL:storeURL options:nil error:&error])
{

参考サイト
http://stackoverflow.com/questions/7274711/run-logic-tests-in-xcode-4-without-launching-the-simulator
http://iamleeg.blogspot.com/2010/01/unit-testing-core-data-driven-apps-fit.html

 Posted by at 22:51

AS3のように記述できるHTML5ゲームエンジン

 プログラミング  Comments Off on AS3のように記述できるHTML5ゲームエンジン
Jan 262012
 

Flashライクな操作方法で開発が出来るライブラリ「Arctic.js」
Actionscript3に似たAPIでHTML5のCanvasへの描画操作が出来るゲームエンジン。どのくらいの負荷になるか簡単なデモを作成して試してみた。SheetMovieClip(画像のパラパラアニメ)のsprite数1200くらいから表示は重くなるがPC(2011年の一般的なモデル)では操作不能ではないレベル。iPhone4では50でも描画は遅くなる。速度次第で選択すれば実用性は十分。

 

 

以下からライブラリを入手できる。

https://github.com/DeNADev/Arctic.js

APIにはaddChildやMovieClipという名称のものがありFlashからのモバイル移行が楽。immediateモードのHTML5のCanvasはとても描画の柔軟性がある。

API解説は以下が詳しい

http://www40.atwiki.jp/spellbound/pages/1780.html

HTMLCanvasについて概要

http://tutorials.jenkov.com/html5-canvas/overview.html

 Posted by at 15:34

iCloudとCoredataと内部ファイル構造

 プログラミング  Comments Off on iCloudとCoredataと内部ファイル構造
Jan 192012
 

Objective-CでCoredataをiCloudで異なるデバイス間で同期する時のファイル構成を図解。entitlementsファイルで指定したキーと

URLForUbiquityContainerIdentifierおよびNSPersistentStoreCoordinatorの関係。NSPersistentStoreUbiquitousContentNameKeyやNSPersistentStoreUbiquitousContentURLKeyの関係についてのまとめ。

ここではiCloudで単一のCoredataを使う場合を考える。ここで仮想の条件で

  • app照合IDはcom.f60k.lab(以下appID)
  • individual IDはA0EEE752E ($(TeamIdentifierPrefix)はindividual IDで置き換えが可能。)
とした。
entitlementsファイルで指定した「A0EEE752E.com.f60k.lab」という文字列はURLForUbiquityContainerIdentifierで参照できる。この文字列はmobileprovisionファイル中にも記載されている。この名前をベースにしてコンテナ内にフォルダ(ここではA0EEE752E~com~f60k~lab)が作成される。
その中にフォルダ(ここではlabdb)が作成される。このフォルダはNSPersistentStoreUbiquitousContentURLKeyで指定した名称が使われる。このフォルダに永続ストア(ここではsqliteファイル)を同期するために必要な情報をやりとりした結果(Coredataの変更差分ログファイル)が格納されるのだが、デバイスごとに固有のフォルダが作成される。例えばiPhoneとiPadという2つの場合は図のように2つの「mobile.デバイスID」というフォルダがさらに作成され、その中にNSPersistentStoreUbiquitousContentNameKeyで指定した名称でフォルダが作られ、その中にログファイルが格納される。つまりデバイスが何台ありどのデバイスがどういう変更をどのタイミングで行ったかがわかる。このファイルを受信するとアプリケーションドキュメントフォルダのsqliteが更新される。
DBとなるsqliteはiCloudと同期しないアプリケーションドキュメントフォルダの位置に保存されているが、iCloud中にDBファイルを保存することもできるが.nosyncとサフィックスを追加しておく。nosyncしなければ同期DBファイルそのものを一括で同期することもできるが、サイズが小さい場合に限った方が賢明。

UIDocumentベースのケースについてはまた別の機会。

参考サイト

http://goddess-gate.com/dc2/index.php/post/452

 Posted by at 03:07

Xcodeでbuild番号を自動で増やす方法

 プログラミング  Comments Off on Xcodeでbuild番号を自動で増やす方法
Jan 172012
 

CFBundleVersionを使ってXcodeのビルド(Build)の数値を自動的に増やすスクリプトをビルド設定に追加する。スクリプトを追加するとビルド毎にBuild番号が自動で1つ増えるようになる。

Build Phaseに実行するスクリプトを用意する

copy bundle resoucesの前にadd build phaseして以下のスクリプトを追加する。このスクリプトは数値をインクリメントしinfo.plistの特定にキーに書き込んでくれる。

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" ${PROJECT_DIR}/${PROJECT_NAME}/${PROJECT_NAME}-Info.plist)
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" ${PROJECT_DIR}/${PROJECT_NAME}/${PROJECT_NAME}-Info.plist

特定のキーを設定する
info.plistにCFBundleVersion(表示名は異なるので以下画像の選択項目)を追加する。値に数字の0を入れる。

参考元

http://blog.suda.pl/2012/01/auto-increment-build-number-in-xcode-4-2-fixed/

 Posted by at 02:53

iCloudを使う場合のEntitlementsの設定方法

 プログラミング  Comments Off on iCloudを使う場合のEntitlementsの設定方法
Jan 162012
 

Xcodeにおけるentitlementsとはアプリに対する機能やセキュリティの許可を承認するための設定のことである。デフォルトではほぼすべて無効に設定されている。適したキー名と値のペアでデフォルトを上書きすることで有効になる。

  • iCloudのデータ保存領域(document/key-value)を使いたい
  • バックグラウンドでプッシュ通知(Push notification)を使ってユーザに情報を伝えたい
  • サンドボックス(sand boxing)と呼ばれるセキュリティ機能を使いたい(MacOSXのみ)

iCloudのentitlement

ユーザドキュメントの保存についてみていく。iCloudでこれをサポートするには、XcodeでターゲットのSummaryで設定を行う。XcodeでチェックボックスをONにするだけで.entitlementsファイルが作成される。間違ったり動作がおかしいならentitlementsファイルを削除し、再び作成すればよい。

iCloud entitlements setting

ただし、事前にAppleのポータルでAppIDを登録し、さらにAppIDのiCloud利用ができるようにポータルで設定を行うこと。最後にポータルからProvisioningファイルを発行し直す。ProvisioningファイルにはiCloudの有効化設定が含まれる。(以下ではcom.f60k.labというAppIDを想定)

具体的には、com.apple.developer.ubiquity-container-identifiersというキーに$(TeamIdentifierPrefix)com.mycompany.myapplicationという値を設定するという動作を自動でやってくれている。

TeamIdentifierPrefixという文字列がentitlementsファイルに自動追加されるのでテキストフィールドにはこのPrefixは入力する必要はない。

さらにこの値を複数設定すれば、(同じチームの)他のアプリのドキュメントにアクセスする事も出来る。

参考

以下が詳しい。
http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1
http://developer.apple.com/library/ios/#documentation/Miscellaneous/Reference/EntitlementKeyReference/EnablingiCloud/EnablingiCloud.html#//apple_ref/doc/uid/TP40011195-CH2-SW1

 Posted by at 03:54