AIR&Cakeによるアプリ制作 | エモンのブログ(スマホアプリ作成日記)

エモンのブログ(スマホアプリ作成日記)

エモンのブログです。

GooglePlayとAppStoreにアプリをリリースしてます。
「詰将棋パラダイス」4500問無料で公開。
「みんなのしょうぎ」投票型の将棋対局。いずれもソーシャルアプリなので、ソーシャルゲーム作成に興味があるかたは是非ご覧ください。

AIR&Cakeでアプリを作ってます。
クライアントはAIRで、非同期でサーバと通信を走らせるスタイルのスマホアプリはDAUを稼ぐアプリとして非常に可能性があると個人的に思ってます。すなわちソーシャルゲームですが。
今回は開発中のことやDB周辺に関する部分について、自分のやり方を書いてみます。

その1:test()メソッドを書いて開発をラクに
サーバと通信するスタイルのAIRアプリではPHP側はおそらくContent-Type:text/plainで出力し、対応することが多いかと思います。FlashサイドでURLLoaderインスタンスをURLLoaderDataFormat.VARIABLESに指定してPHPではURL変数を返す感じですね。
d=0&param1=0&param2=10
こんなURL変数をechoするようにします。
なお、PHP側のフレームワークはCakePHPを使ってます。

FlashとPHP連携テストしているときに、PHPにミスがあると実行時エラーとなります。
きっとURLdecodeエラーみたいなのが出ると思います。これはechoで出力する文字列がURL変数でなかったり、phpエラーが出てたりしているとこういう状況に陥ります。Cakeの場合はparse errorになってたりしてます。
まさかこれをFlashを実行するときにだけテストするわけにはいきません。効率が悪いです。PHPのミスを単体テストで発見しておきたいですよね。

そこでtests_controller.phpを作成し、アプリ上で使用している全てのモデルをusesに指定します。
そして全てのモデル上でなんらかの関数を呼べば、parse errorを感知できますよね。
なのでダミーでtest()という関数を全てのモデルで定義しておきましょう。
そうしておいてtests_controller.phpのtest関数から全てのモデルのtest()関数を呼ぶようにしておけば良いです。
modelはapp_model.phpを継承してますので、app以下にapp_model.phpを作成し、そのスーパーなモデル内で1個test()関数を定義しておけば良いですね。
テスト時はtests/testを呼べば全てのモデルにてparse errorがないかチェックできます。

その2:cakeErrorの記述
CakePHPを使っていますが、エラー処理を簡単にするためにcakeErrorを定義しておきましょう。
これは「トランザクション処理」の時に役に立ちます。
app以下にapp_error.phpを記述し
class AppError extends ErrorHandler {
function error($params=null) {
Configure::write('debug', 2);
$this->autoRender =false;
echo 'd=0&error=1';
}
}
なにかPHP上で問題があったタイミングで
$this->cakeError('error', $param);

という感じで呼べばAppErrorのerror関数を読んでくれます。この時点で強制的に
d=0&error=1

を出力するのでFlashサイドでURLVariables::error=1を感知したらFlash上でもエラー処理を行うようにしておけばOKですね。

その3:トランザクション
InnoDBでテーブルを作る環境にあればトランザクション処理は入れたいですね。
app以下のapp_model.phpにて
function begin() {
$db = & ConnectionManager::getDataSource($this->useDbConfig);
$db->begin($this);
}
function commit() {
$db = & ConnectionManager::getDataSource($this->useDbConfig);
$db->commit($this);
}
function rollback() {
$db = & ConnectionManager::getDataSource($this->useDbConfig);
$db->rollback($this);
}
を記述してトランザクション用のbegin, commit, rollback関数を用意しましょう。
さらに同クラスにCRUD関数も追加します。CRUDとはCreate, Read, Update, Deleteです。
Cakeの場合はDB更新系の関数が失敗するとfalseが返るだけなので、ここでfalseならばCakeErrorを呼ぶようにしときましょう。
例として登録関数を示します。
function regist($data) {
$this->create();
if(!$this->save($data)) $this->cakeError('error', null);
}
これで登録に失敗するとcakeErrorが呼ばれ「d=0&error=1」というエラー文字列がFlashへ返ります。※create()しないと更新になってしまうので注意じゃの
なので、複数の処理を1つの処理として扱いたい(アトミックに実行する)場合は以下のようになります。※modelでの記述
$this->begin();
$this->regist($data1);
$this->regist($data2);
$this->commit();
これで$data1の登録はできたが$data2の登録ができなかった場合、cakeErrorが走りcommitされません。従って
$data1も登録されません。これでトランザクションが実現しました。

cakeErrorを呼ぶところはDB更新する箇所にのみ限定して置いておくとわかりやすくていいですよ。
app_modelに更新、削除の関数を作っときましょう。ついでにfindByIdをただ呼ぶだけのgetByIdを作りました。
function update($data) {
if(!$this->save($data)) $this->cakeError('error', null);
}
function del($id) {
if(!$this->delete($id)) $this->cakeError('error', null);
}
function getById($id) {
$result = $this->findById($id);
return $result;
}

cakeErrorはどこから呼んでも処理を打ち切ってくれるので便利ですね。

デコポニテの魔女」の提供でこのブログは書かれております。
デコポニテの魔女はAndroid端末用簡易右スクロールシューティングゲームです。
Technology By: Adobe AIR & CakePHP