アプリ開発で、ユーザーからデータ復旧を求められた場合 サンプルソース
アプリを開発していると、課金や障害や端末事情で、ユーザーからデータ復旧を求められる場合があります。データが破損した場合も。
ソシャゲならサーバーデータ変更して終了かもしれませんが、普通のアプリはユーザーの端末内にセーブデータなどを保存しているので、ますますどうしようもない感じがします。
その状況を打破すべく、フロントエンド(ActionScript)と、サーバーサイド(PHP)のサンプルプログラム&キャプチャを公開しましたのでどうぞ~。データファイルはuid(ユーザーごとに割り振るユニークID)と同じファイル名を、PHPと同じ階層においておけばOK。add:が先頭についてるデータはインクリメントの指定です。復旧が済めば自動でリネームされる(データファイル名がend~となる)ので、進行状況も一目瞭然。変数や関数は名前からなんとなく判断してくださいw 一応グローバル対応もしてます。 loadTxtはAPIにPOSTでアクセスしてるだけで、showDialogは英語のままですw 最後に再起動させてるのは、その方がデータ的に安全だからです。
これでほぼすべてのデータがどうにかなるので、課金処理エラーにも辟易しなくて済みます。
・・・しまった!こんなのばかり作ってしまって、肝心のゲームが足踏み状態にw
そういえば今日未明に、iOS9やらAppleの新しげな取り組みが発表されまくってましたね。AppleWatch入手できたらアプリ作ってみたいなあと思ってたら、もう本が発売されてるw
▼データファイル サンプル UTF-8で保存する
add:mahouseki=100 userLv=99
▼フロントエンド サンプルコード
Btn(m.BtnRepair, onRepair); function onRepair():void{ //ローダー表示 showLoader(); var loaderTimer:Object = {}; T(loaderTimer, { d:8, st:function():void{ endLoader(); showDialogNetworkError(); }}); //ここでAPI(repair.php)にアクセス var url:String = _DOMAIN+"api/repair/repair.php"; loadTxt(url, onLoad, onError, { uid : _uid }); function onLoad(s:String):void{ trace("L45 onLoad s = " + s); RT(loaderTimer); endLoader(); var s2:String = RemBlank(s); if(!s2 || s2.length <= 2){ showDialog1(_isEnglish ? "No recovery data for now." : "現在復旧データはありません。"); }else{ showDialog2( _isEnglish ? "Do you want to recover the data?" : "データを復旧しますか?", onRecovery); function onRecovery():void{ //リカバリー処理 var lineArray:Array = s.split(_LINE); for(var i:uint=0; i<lineArray.length; i++){ var s3:String = lineArray[i]; if(RemBlank(s3)){ var key:String = s3.split("=")[0]; var value:Object = s3.substr(key.length+1); if(key.substr(0, 4) == "add:"){ //インクリメントの処理 key = key.substr(4);//4); addLocal(key, value); }else{ saveLocal(key, value); } } } flushLocal(); showDialog1( _isEnglish ? "Done!\nApp is automatically terminated.\nPlease restart app.\nSorry to trouble you." : "データを復旧しました!\nアプリを自動的に終了します。\nお手数ですがアプリを再起動してください。", onReboot, onReboot); //データ終了通知の送信 loadTxt(url, function():void{}, null, { uid : _uid, isEnd:true }); function onReboot():void{ NativeApplication.nativeApplication.exit(); } } } } function onError():void{ trace("L49 onError"); RT(loaderTimer); endLoader(); showDialogNetworkError(); } }
▼サーバーサイド repair.php サンプルコード
<?php mb_internal_encoding('UTF-8'); $ua = $_SERVER['HTTP_USER_AGENT']; //if(!strstr($ua, 'AdobeAIR') && !strstr($ua, 'Shockwave Flash')){ return; } //if(isset($_POST["devType"])){ //復旧用データとなるテキストをロードして表示する。 if(isset($_POST["uid"])){ //レストアファイル存在チェック if(!file_exists($_POST["uid"])){ //存在しなければ、何も返さない }else{ //存在していればロード echo file_get_contents($_POST["uid"]); if(isset($_POST["isEnd"]) && $_POST["isEnd"]==true){ //復旧完了時の処理 //ファイル名変更 end.~ rename($_POST["uid"], "end".$_POST["uid"]); } } } ?>
▼画面キャプチャ
最近つくったゲームアプリ
放置系モナータップRPG - Google Play の Android アプリ
iTunes の App Store で配信中の iPhone、iPod touch、iPad 用 放置系モナータップRPG