AppStoreにアップする(15=END)

 さてさて。
 ダイスを回せ!は、起動するとそれまでの飲み会や登録メンバーの記録が残ってる仕様なわけですが、こいつを実現するためには「メモリ上に展開された各オブジェクトの状態とその連携をアプリ終了後も保持し再現可能」とするメカニズムが必要なわけです。

 アプリ終了時には消えてなくなる(揮発性)メモリ上のオブジェクトの情報を、電源が切れても消えない(不揮発性)記憶装置、例えばiPhone本体のフラッシュメモリとか、ネットワーク上のサーバーなどへ保存しておいて

$テン*シー*シー-5

 アプリ起動時に、その情報を元にアプリ終了時のオブジェクトの状態を揮発性メモリ上に再現する。

$テン*シー*シー-6

 こういう機構をAppleでは「iPhone OS Core Dataチュートリアル」の中で永続化メカニズムって呼んでます。
 簡単なものではその(44)でもとりあげてるNSUserDefaultsクラスを使った設定値の保存、読み込みなんかがこれにあたるわけです。
 NSUserDefaultsクラスが受け付けるNSMutableArray、NSMutableDictonaryは階層的に組み合わせることも可能で、writeToFile:atomically:呼び出し一発でiPhone本体のフラッシュメモリへファイルとして書き出されるし、initWithContentsOfFile:一発で読み出されもするので、やろうと思えばこれだけで永続化メカニズム完了ってわけなんですが…
 Appleも言うように、書き出されるファイルの大きさが1MBを超えるような大きさになる場合、この方法は、あんまり効率的ではないわけですよ。

$テン*シー*シー-1

 なわけでダイスを回せ!クラスの各オブジェクトの状態とその連携を再現するにはちと荷が重い。

 じゃ、どうするかというと独自に定義(汎用性が無くなる事と引き換えに高速化を実現する)したフォーマットのファイルを作るか、SQLite APIを通してデータベースファイルを利用する事になるわけです。
 そしてこれらをもっと簡易に、そして効率的に扱えるようにしたのがCoreDataフレームワークなわけでして、まあ、これをAppleはプッシュしてるわけです。
 実際、使い勝手もいいし積極的に使いたいと思ってるんですが、ダイスを回せ!作成時はCoreData経験値が浅かったので、無難にSQLiteを使う事にしました。

 ということで、まずは各クラスのメンバ変数や関連をER図、その(151)を覚えてるかな~、に仕上げることから始めます。

 Groupクラスに組み込まれているDescountAttributeクラスはひとまとめにしてgroupsエンティティにしてみっかとかsexとstarsメンバ変数のクラスはどっちもSOneDiscountAttribute構造体だからdiscount_attributesエンティティで管理だとか

$テン*シー*シー-2

 逆にMemberクラスのexclusionsは可変だしmembersエンティティにひとまとめにはできねーなとか、いろいろ考えながらER図を作っていく。

$テン*シー*シー-3

 で、こうやって作りあげたER図を元に、実際のデータベースのテーブルを定義してSQLite APIを使って

$テン*シー*シー-7

 を実現してるのが
Recorder

 というクラスで、このRecorderを使って、Group管理をおこなってるのが
DiceHistory

 というクラスになります。
 これが、アプリ起動時に呼び出されるMainAppDelegateのapplication:didFinishLaunchingWithOptions:メソッドでやってる
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[DiceHistory sharedHistory] load];

なわけです。

 ちなみにPersonクラスにはUIImageがあるわけですが、こいつはデータベースに直接放り込むことはせず、ドキュメントフォルダにphotosというサブフォルダを作り、そこにpersonsテーブルの主キーであるIDの値を文字列にしたものを名前とする画像ファイルとして保存するようにしてます。
 主キーはpersonsテーブル内で一つのレコードを特定するのに使うものなので、重複はしない事から、ファイル名に使うのにちょうどいいわけですな。

$テン*シー*シー-4

 テーブルとか主キーとかがわからない人はその(74)あたりから地道に読みなおしていきましょう。

iPhoneアプリ開発 目次3

 200回記念アプリなんで、あっちゃこっちゃの記事の集大成になってるんですわ。主キーについてはその(80)でPRIMARY KEYとして紹介。

 これでダイスを回せ!の永続化メカニズムが準備できたわけです。
 あとは最後に開いてるグループがなんだったかを記憶し、起動時にそのグループを選択し基点となるTotalPaymentViewControllerまでドリルダウンを実行するようにして完了。

$テン*シー*シーX
こいつね↑

 これがMainAppDelegateでやっているNSUserDefaultsへの利用中のグループのデータベース上のレコードIDの書き込みであり、didFinishLaunchingWithOptions:メソッドではこのIDが-1でないなら、そのグループを対象としてGroupTableViewControllerのcallTotalPaymentViewControllerメソッドを呼び出し、画面のドリルダウンをおこなわせてます。

 まあ、この起動時ドリルダウン作業は、iOS 4.0のマルチタスク時代となった今では基本的に利用されないわけですが、ユーザーが手動で待機アプリリストから削除する場合用に、なんらかの保証はしとかないと駄目ですね。
 iOS 4.0環境でも毎回終了、起動させるようにしたければ、plistに

  Application does not run in background

 を追加してチェックを入れればいいんですが、せっかくのマルチタスク機能だし、これから作るなら、まじめにapplicationDidEnterBackground:やapplicationDidBecomeActive:メソッドで対応が正解ですな。

 最新の「iOS アプリケーションプログラミングガイド」には、マルチタスクをサポートする方法についての説明が載ってます。以前、読んだからといって放置してると置いてきぼりをくっちゅうよん。

 ということで、ダイスを回せ!完全版ソースをアップして、今回のプロジェクトの説明はおしまい。

 AppStoreへの登録は、iOS Dev CenterにiOS Developer Programに加入した人にだけ出てくるリンクでiTunes Connectに進んでおこなう。

$テン*シー*シー-1
ここに出てくるのじゃよ↑

 次世代Xcodeでやってもーた私が言うのもなんですが、守秘義務あるのであんまり詳しくは言えないけど、とりあえずiTunes Connectのトップページの説明書は相変わらず英語だけど、iTunes Connect→Manage Your Applicationsページにある説明書(Developer Guides)はJapaneseが提供されてて、かなり細かく手ほどきしてくれてます。

 あと、Applicationには開発用ではなく配布用の証明書を使う、当然App IDにはワイルドカードは設定できない、でもって作成したアプリはzipファイルにして送るとか、ここらへんはiOS Provisioning Portal(iTunes Connect同様iOS Developer Programに加入した人にだけ出てくるリンク)サイトの右上にPortal Resourcesとして用意されてるPDFドキュメントProgram User GuideのDistributionの章に詳しく載ってます。
 残念ながらこっちは日本語で書かれたドキュメントは見つからず。

 カワサキさんの本に詳しく説明されてるんじゃないかと期待。本が届き次第レポートする予定。

サルにもできる iPhone 同人誌の創り方(CD-ROM付)amazonで買う

 サイコロを回す時に音を出すようにしたり、いままでの公開ソースにいくつかの追加処理が加わっています。ThrowDiceViewControllerへの登録画像の受け渡しとか、説明しなかった部分は各自でデバッガを駆使して解析してみてくださいね~。

------------
サンプルプロジェクト:Dev-final.zip