アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

Monacaデバッガーのカスタムビルド版を使ってみよう

Monacaアプリをデバッグする際には3つの方法があります。



  1. Monaca IDE上のプレビューを使う
  2. Monacaデバッガー(App Store/Google Playからダウンロード)を使う
  3. アプリをデバッグビルドする
  4. Monacaデバッガーのカスタムビルド版を使う


プレビューは簡易的に表示や機能を試せますが、スマートフォンならではの機能は利用できません。Monacaデバッガーは動作の確認はできますが、幾つかの制限があります。



  1. あらかじめMonacaデバッガーに組み込まれたCordovaプラグインしか使えません
  2. USBデバッグに対応していません
  3. Monacaデバッガー経由でのアプリインストール機能、ネットワークインストールに対応していません


アプリをデバッグビルドすることもできますが、コードを編集するたびにアプリをインストールし直すのは手間がかかります。そこで今回はMonacaデバッガーのカスタムビルド版を紹介します。



Monacaデバッガーカスタムビルド版の特徴



  1. 自作プラグインをはじめすべてのCordovaプラグインが使えます
  2. ネットワークインストール対応
  3. Chromeを使ったデバッグに対応
  4. Monaca IDE上でビルド


カスタムビルド版の作成方法



まずはMonaca IDEを使ってプロジェクトを開きます。





環境一覧



アプリとしてビルドしますので、設定メニューからビルド設定を行います。





設定メニュー



開発者証明書などをアップロードしてください。





iOSビルド設定画面



そしてデバッガーメニューからiOS向けデバッガーのインストールを選択します。Androidの場合はAndroid向けデバッガーのインストールを選択してください。





デバッガーのインストール



今回はビルドしてインストールの方を選択します。





ビルドウィンドウ



ビルドする際にはプロビジョニングプロファイルが必要です。iOS Dev Centerであらかじめ作成しておいてください(iOSの場合)。





プロビジョニングプロファイルの指定



ビルドが終わったらダウンロードして、iTunesなどを使ってインストールします。





ビルド完了






Monacaデバッガーのカスタムビルド版は見た目はMonacaデバッガーと変わりません。ただし任意のMonacaプラグインが使えることと、LocalKitを使っている時にGoogle Chromeを使ったデバッグがサポートされます。使い慣れたDevToolsを使えばMonacaアプリ開発が格段にスムーズになるはずです。



任意のCordovaプラグインが使えるのはGoldプラン以上ですが、これによってMonacaアプリの可能性が格段にあがります。ぜひお試しください!

ブレークポイント対応!Android用MonacaアプリをGoogle Chromeでリモートデバッグ!

アプリ開発の効率をあげるためにはどうすれば良いでしょう。開発していて、書いたコードが一発で問題なく動くことなどほとんどない訳で、大事なのはデバッグになります。問題のありそうな箇所をいち早く突き止めて、修正していくことでアプリの精度を高めていくのが大事です。



Objective-CやSwift、Javaといったネイティブのプログラミング言語とはちょっと切り離されているハイブリッドアプリの場合、そのデバッグ方法も異なってきます。今回はMac OSXを使ってAndroidMonacaアプリのデバッグ法を紹介します。



Monacaデバッガーのダウンロード&インストール



Monacaデバッガーは通常版ハイパフォーマンス版が用意されています。通常版はOS標準のWebView、ハイパフォーマンス版はCrosswalkというWebViewエンジンを利用する点が異なります。利用するMonacaデバッガーはどちらでもかまいませんが、今回紹介するGoogle Chromeを使ったデバッグ法はそれぞれ対象となるAndroidのバージョンが異なりますのでご注意ください。





Monacaデバッガー



  • ハイパフォーマンス版:Android 4.0以上
  • 通常版:Android 4.4以上


なお、利用に際してGoogleアカウントが必要になりますのでお持ちでない場合はアカウントを作成してください(無料です)。



AndroidバイスでUSBデバッグを有効にする



デバッグをはじめるにあたり、Androidバイスで開発者向けオプションを有効にし、USBデバッグを許可している必要があります。忘れずにチェックしてください。





開発者向けオプション



実際のデバッグ時には母艦とAndroidバイスをUSBケーブルでつないでください。



Monacaデバッガーでアプリを立ち上げ



ではいよいよMonacaデバッガーを起動します。





ログイン画面



ログイン画面が出たら、MonacaのユーザID/パスワードを入力してログインボタンをタップしてください。ログインできるとMonacaクラウド上のプロジェクトが一覧表示されます。





プロジェクト一覧



この中からデバッグしたいプロジェクトをタップします。



たとえばこのようにアプリが立ち上がったらデバッグ開始です。





Monacaアプリ起動



Google Chromeを使ったデバッグ



Android 4.0からデスクトップ版Google Chromeを使ったデバッグができるようになりました。Monaca IDEで提供しているデバッグパネルよりも詳細なデバッグが可能になっています。



まず、Google Chromeから chrome://inspect を開きます。





Google Chromeインスペクタ



そうするとDevicesとして接続されているAndroidバイスと起動しているエミュレータが一覧で表示されます。今回のように実機で実行している場合、そのアプリ名とバージョン、開いているHTMLファイルのタイトルなどが表示されています。
デバッグしたいアプリののInspectをクリックします。





DevTools起動



DevToolsが表示されますので、後はソースを見たり、DOMの構造を確認したりできます。



ブレークポイント/DOMのハイライト



Google Chromeを使ったデバッグでは、これまでは難しかったブレークポイントを追加することもできます。





ブレークポイントを設置



こちらはブレークポイントで停止しているところ。変数の内容も確認できます。





ブレークポイントで停止



コンソールでconsole.logの内容も確認できます。





コンソールの表示



実機でもDOMがハイライトされるので、どこにフォーカスしているかが一目で分かります。





DOMのハイライト



ブレークポイントで停止している時の表示です。続行ボタンをタップすればJavaScriptが実行されます。





ブレークポイントでの停止中



実機を使ったデバッグの場合、カメラや加速度、プッシュ通知周りの実装確認が容易になることでしょう。



ここまで詳細にデバッグができると、開発のしやすさが格段にあがってくるのではないでしょうか。



iOS/Androidの違い



iOSではこれまでデスクトップ版Safariと組み合わせたデバッグが一般的でした。Androidではweinreが使われてきましたが、若干機能が足りないと感じることも多かったでしょう。この方法で紹介するようにAndroidでもUSBデバッグが行えるようになったので、Webブラウザ(SafariGoogle Chromeか)という以上の違いはほとんどなくなっています。



なお、Androidはアプリがバックグラウンドに入っていてもDevToolsを接続することができます。バックグラウンドでの処理を確認したり、フォアグラウンドになっていない時の通知処理などを確認するのにはぴったりと言えそうです。Safariはバックグラウンドにすると接続が切れてしまいます。



まとめ



Webでは元々ブラウザの画面解像度が様々でウィンドウの大きさも千差万別でした。そのためレスポンシブWebデザインに代表されるようなあらゆるデバイスで意図した通りに表示させる技術に長けています。それはAndroidのように多様性のある解像度をもったデバイスでの表示に役立つことでしょう。



その開発において普段使い慣れたデバッガを使えれば、表示や処理の確認がさくさく進められるはずです。ぜひGoogle Chromeを活用してMonacaアプリ開発を効率的に進めてください!

WinCacheGrindの替わりにWebgrindを使ってみよう

森川です。

今回はXdebugを使用したプロファイル結果を閲覧するwebgrindの紹介です。

インストールはまずプロジェクトトップページダウンロードページからダウンロードしてアクセス可能なところに展開します。

次に、プロファイル結果を保存しているディレクトリをconfig.phpのprofileDirに設定します。あとは、セレクトボックスに表示されれば終了です。

webgrindはPHPで記述されたWebアプリなので、Xdebugを使用しているサーバ上で動作させることができます。今まで使っていたWinCacheGrindとwebgrindを比較した際の良い点、悪い点をまとめてみました。

1. プロファイル結果をクライアントに移す必要がない

今回使用してみて一番よいなと思ったのが、サーバ上で動作させることができるので、プロファイル結果をWinCacheGrindがインストールされているマシンに移さなくてもよいということです。プロファイル結果は数MBにもなるので、結構移すのが面倒だったりするので、これは大きなメリットです。

ただこの点に関しては、同一のマシンにWinCacheGrindやKCacheGrindなどがインストールされている場合は、あまりメリットはないかも知れません。

それと、webgrindもPHPで記述されたWebアプリなので、プロファイル結果を閲覧する場合のフローは以下のようになります。

Xdebugでプロファイリングを有効にする

スクリプトを実行

Xdebugを無効にする

webgrindのページにアクセス

一度Xdebugを無効にしないと余計なプロファイル結果が出てきてしまうので、要注意です。

2. スクリプトをWebから閲覧できる

これもWebアプリならではだと思いますが、時間がかかっている関数の呼び出し部分をブラウザ上で閲覧することができます。

ちょっとしたことですが、結構便利だと思います。

以下は悪い点です。

3. 動作が遅い

WinCacheGrindもかなり遅いですが、webgrindの方が動作がもっさりしている感じがします。とくに関数の詳細(中で何を呼んでいるかなど)を閲覧するのにサーバへのアクセスが発生するようで、もっさり・イライラしてきました。

4. 操作性が悪い

WinCacheGrindでは、関数の呼び出しが階層化されていて、ダブルクリックで下の階層に移っていくことができますが、webgrindでは階層化されていません。




階層化されていないという以外は、特定の関数内で何が呼ばれているか、その関数がどこから呼び出されているか、何回呼び出されているか、どれだけ時間がかかったのか、などの基本機能はあります。



とりあえず、簡単にですが使ってみてですが、結構使えるかも!というのが印象です。

開発はわりと活発に行われているようなので、今後に期待です。

FirebugでPHPをデバッグするツールまとめ

こんにちは、亀本です。最近は体調がすこぶる絶不調です。季節の変わり目なので、皆さんも気をつけてください。

さて、ちょろちょろと話題に上ることの多いFirefoxを使ったPHPデバッグ手法ですが、いくつか出てきたのでこの辺でサクッとまとめておこうかと思いました。
結果的に、だいぶ膨らみましたが。。。まとめ力ないなorz

1.Buggy クラス



AJAX magazine というサイトで公開されていたサンプルスクリプトで、クラス1つだけの小さなライブラリです。
以前、PHPプロ!ニュースでもご紹介した方法です。

この方法は、PHPのエラーをハンドリングし、その内容をscriptタグに出力し、console.info()を用いてFirebugのコンソールに渡す、という仕組みです。そのため、Firebugは必須です。

記事掲載当時は、buggy.class.phpがダウンロードできたのでしょうか。。。リンク先には今はダウンロードリンクがなく、サンプルコードが掲載されているだけなので、コピペするなりして保存してください。
一応、利便性のために現時点でのbuggy.class.phpのコードをこちらのブログにも掲載しておきます。



<?php
/**
 * Buggy inside Firebug - Advanced
 * 
 * @package GONX
 * @author hatem <hatem at php dot net>
 * @website http://phpmagazine.net
 * @copyright Copyright (c) 2005-2007
 * @version $Id: buggy.class.php,v 2.2 2007/02/10 04:10:12 hatem Exp $
 * @access public
 **/
class buggy {

	function _init(){
		$old_error_handler = set_error_handler(array("buggy","ErrorHandler"));
		define ("FATAL",E_USER_ERROR);
		define ("WARNING",E_USER_WARNING);
		define ("NOTICE",E_USER_NOTICE);
		// configure reporting level
		error_reporting (FATAL | WARNING | NOTICE);	
	}

	/**
	 * Buggy::getmicrotime()
	 * 
	 * @return 
	 **/
	function getmicrotime(){
		$mtime = microtime();
		$mtime = explode(" ",$mtime);
		$mtime = $mtime[1] + $mtime[0];
		return ($mtime);
	}

	/**
	 * Buggy::SetMicroTime()
	 * 
	 * @param $module
	 * @return 
	 **/
	function SetMicroTime($module)
	{
		global $Buggy;
		$Buggy[$module] = Buggy::getmicrotime();
		return $Buggy[$module];
	}
	
	/**
	 * Buggy::GetExecutionTime()
	 * 
	 * @param $module
	 * @return 
	 **/
	function GetExecutionTime($module)
	{
		global $Buggy;
		$end = Buggy::getmicrotime();
		$res = $end - $Buggy[$module];
		return $res;
	}

	/**
	 * Buggy::Track()
	 *
	 * @param $module
	 * @param $msg		additional message to display
	 * @return 
	 **/
	function Track($module, $msg = '') {
	
		global $Buggy;
	
		if (!isset($Buggy[$module])) {
			
			Buggy::SetMicroTime($module);
			
		} else {
			
			$duration = Buggy::GetExecutionTime($module);
			Buggy::logMessage($module,'Notice',$msg,$duration);
		
		}
	
	}
	
	/**
	 * Buggy::logMessage()
	 * 
	 * @param string $module
	 * @param string $type
	 * @param string $message
	 * @param string $duration
	 * @return 
	 **/
	function logMessage($module = '', $type = '', $message = '', $duration = ''){
		if ($module == 'PHPError') {
		
			if ($type == 'WARNING') {
				echo "<script>console.warn(\"[Buggy] - $module [$type] - $message\")</script>\n";
			} elseif ($type == 'Fatal') {
				echo "<script>console.error(\"[Buggy] - $module [$type] - $message\")</script>\n";
			}else{
				echo "<script>console.info(\"[Buggy] - $module [$type] - $message\")</script>\n";
			}
				
		} else {
			echo "<script>console.info(\"[Buggy] - $module [$type] - $message - Execution Time: $duration \")</script>\n";
		}
	}
	
	/**
	 * Buggy errors manager
	 * 
	 * @param $errno
	 * @param $errstr
	 * @param $errfile
	 * @param $errline
	 * @return 
	 **/
	function ErrorHandler ($errno, $errstr, $errfile, $errline) {
	  switch ($errno) {
	  	case FATAL:
		Buggy::logMessage('PHPError', 'Fatal', "{$errno} : $errstr - Fatal error in line ".$errline." of file ".$errfile);
		exit(1);
		break;
		
		case WARNING:
			Buggy::logMessage('PHPError', 'WARNING', "{$errno} : $errstr - WARNING error in line ".$errline." of file ".$errfile);
		break;
		
		default:
			Buggy::logMessage('PHPError', 'Notice', "{$errno} : $errstr - Notice error in line ".$errline." of file ".$errfile);
		break;
	  }
	}

}
?>


使い方は単純で、buggy.class.phpをインクルードしてInit()メソッドを実行したら、あとはエラーが発生した個所にscriptタグが挿入されます。


<?php
require_once "buggy.class.php";

Buggy::Init();

trigger_error("わーにんぐ", WARNING);
trigger_error("のーてぃす", NOTICE);
trigger_error("ふぇーたるえらー", FATAL);
?>

ハンドリングしているのは上記の3つのエラーログのみです。
このサンプルはtrigger_errorでエラーを発生させているので、当然ですがFATALで止まります(^^;

かなり偏った実装なので、このままだとデバッグを行うというよりは、エラーログを取得するのが主目的になります。
ですが、ソースは単純で拡張も容易なので、logMessageメソッドを拡張したり、独自のデバッグ情報取得メソッドを実装してもよいでしょう。

簡易なライブラリですが、ややこしいことはほとんど考える必要もないので、小さなプログラムの開発を行う時には、わりと気楽に使えそうです。


2.PEAR::Log



言わずとしれたPEARライブラリのLogクラスですが、実はFirebugにログを出力する機能を備えていました。
これは先日、こちらの記事によって有名になった機能です。
案としては結構前からあり、今年の5月にリリースされた1.9.11での実装だったんですが、あまり知られていない機能だったようです。

かくいう自分もこんな話は忘却の彼方でした(^^;
こういうものをパッと発掘して試せる人ってすごいですよね。

基本的な発想はBuggyクラスと同じで、PEAR::Logで発生させたエラーログを、console.info()等を使ってFirebugのコンソールに渡しています。

使い方は・・・上記のサイトを見てもらった方が早いかもしれませんが、せっかくなので載せておくと


<?php
require_once "Log.php";
$firebug =  &Log::singleton('firebug', 'test', 'PHP LOG',  array('buffering' => true), PEAR_LOG_DEBUG);

$firebug->log('わーにんぐ', PEAR_LOG_WARNING);

$firebug->debug('でばっぐー');
$firebug->info('いんふぉ');
$firebug->err('えらー!!');
$firebug->crit('くりてぃかる!!');
$firebug->warning('これもわーにんぐ');

$firebug->debug($_SERVER);

?>

これを実行すると、Firebugのコンソールに各種ログが出力されます。

最初にsingletonメソッドでインスタンスを生成しています。
singletonメソッドは、第1引数に出力ログの種類を指定し、第2引数にその名前、第3引数に識別子、第4引数に出力ログのオプション、第5引数に出力するログレベルの下限を指定します。

後はひたすらlogメソッドでログを出力させています。
debugなどの各メソッドは、logメソッドの第2引数を省略する際のショートカットになっています。

発生させることのできるログの種類は、PEAR::LogライブラリのユーザードキュメントにあるLog Levelsの項を参照してください。

最後のdebugメソッドのように変数を出力しておくことで、デバッグ情報をいちいちwindow上に表示させずにFirebugコンソールで確認する、といったデバッグ手法が利用できます。singletonメソッドの第5引数を変えるだけで出力されるエラーレベルが変更できるので、環境による使い分けも楽に出来ます。


なお、このPEAR::Logライブラリは、以前PHPプロ!Tips MLでも取り上げましたが、このFirebugでのログ取得以外にも多くのログ出力機構をもっています。
Tips MLの紹介内容は少々古く、現在ではPHPプロ!Tips MLの掲載内容に加えて、daemon/display/error_log/mdb2/win(window)/null/sqlite/firebug といった方式が追加されています。
さらに、compositeというハンドラを用いることで、複数の出力を組み合わせて使用することが可能になるなど、かなり多機能です。

Firebugで出せる事自体よりも、そういった高機能ロギングライブラリとして、PEAR::Logはお勧めです。
# Firebugで出す機能がしょぼい、ってことじゃないですよ(^^;

3.FirePHP



FirePHPは、PHPライブラリとFirefoxのエクステンションを併用することで、Firebugに便利なPHP専用コンソールを増設してくれるライブラリ群です。

上記2つがscriptタグを用いてログをJavaScriptで出力する方式だったのに対し、こちらはFirefoxエクステンションを用いることで、HTMLに一切の変更を加えることなくデバッグ情報をやり取りします。
また、そもそも中心となる目的も上記ふたつとは少し異なっており、ログを出力するよりもデバッグ情報をやり取りする事に重点を置いています。

方式としては、PHP側とFirefoxエクステンション側で共通に使用するヘッダとして、「X-PINF-org」接頭辞のついた独自ヘッダを利用してデータのやり取りを行います。
必要な情報は全てHTTPヘッダでやり取りしてしまうので、表示側には余計なデータが現れません。

エクステンションとPHPPEARパッケージはこちらのページからインストールとダウンロードが可能です。

実行するサンプルは以下です。


<?php
require_once "FirePHP_Build/Init.inc.php";

FirePHP::Init();

$hoge1 = "ほげ1";
$hoge2 = "ほげ2";
$hoge3 = "ほげ3";

FirePHP::SetVariable(true, array('REQUEST','TEST1'), $hoge1);
FirePHP::SetVariable(true, array('SESSION','TEST2'), $hoge2);
FirePHP::SetVariable(true, array('APPLICATION','TEST3'), $hoge3); // これは動かない。。

?>


Init()メソッドを呼び出し、あとは適宜SetVariableメソッドでFireBugに渡すようにアサインするだけです

FirePHPエクステンションをインストールしたFirefoxFirebug内に、FirePHPのタグが出来上がっており、上記のスクリプトにアクセスすると、デフォルトでアサインされているスーパーグローバル変数群とともに、SetVariableメソッドでアサインしたデータが表示されます。

なお、デバッグデータの受け渡しが行われるため、セキュリティを気にする必要がある場合にはCookieによるアクセスキー設定が可能です。Init()メソッドの前で
FirePHP::SetAccessKey('適当な文字列');
としてアクセスキーとなる文字列を設定し、これをFirePHP-AccessKeyというクッキーの値として持たせておくことで、クッキーの持ち主にのみデータを送信するようになります。


などなど、色々と面白い機能が搭載、と完璧にいってほしいところなのですが。。。現時点ではところどころ残念なバグもあります(^^;

まず、上記のスクリプトですが、私が試した環境では3つ目のAPPLICATION指定がうまく動きませんでした。
恐らくFirefoxエクステンション側にバグがあるのか、はたまた指定の仕方が違うのか。。。
区分けがわかりにくくなる、という程度の問題ですが、もったいない感じです。

また、実はこのPEARクラス、ところどころ実装が荒っぽかったりするもので、ちょくちょくNoticeを吐くことがあります。。。
この時に、display_errorsがOnだと、そのエラーが出力されることが原因でheaederの受け渡しがうまく行えなくなり、正常に動作しない場合があります。
# 検証の際、最初はデータのやり取り方式を理解していなかったので、これに結構はまりました(^^;
そのため、E_Noticeを表示しない、display_errorsをOffにする、など、何かしらの気遣いは必要になるかもしれません。

ただ、そういった部分を総合的に考えても、このFirePHPは十分に便利なライブラリだと思います。

おまけ:Xdebug Helper



Xdebug HelperFirefoxからXdebugの操作をするFirefoxエクステンションです。
これも以前、PHPプロ!ニュースでご紹介したことがあります。
Firebugデバッグをするわけでもないし、XdebugのON/OFFをFirefoxから行えるというだけなんですが(笑
ついでなので、おまけ的に紹介します。

このエクステンションは、インストールするとFirefoxのステータスバーにアイコンが追加されます。
このアイコンをクリックすることでXdebugデバッグセッションのON/OFFを切り替え、ONにしておくとXDEBUG_SESSION=(設定値)というクッキーを送信してくれるようになります。
大した機能ではないですが、手動でやるといちいち面倒なので、気軽にXdebugによるデバッグが実行できるようになるのはわりと助かりものです。


結局、まとめの割に文章量が多くてまとまっていないというオチに。。。orz
まぁ、なんにせよ(^^;
こういったライブラリが快適なデバッグ環境構築の一助になれば幸いです。