[XCODE] UIWebViewでWebページを表示した際にJSのconsole.logの内容を表示する方法
こんにちは、@yoheiMuneです。
今日は、UIWebViewベースのアプリケーションのデバッグに役立つ、 window.cosole.logの内容をXCODEのコンソールに出力する方法を書きたいと思います。
通常のWebページ開発では、Chromeのデベロッパーツールや、iPhone用のWebインスペクタ(詳細は、こちらを参照)を用いて開発する事で、効率的にデバッグする事が可能です。
しかしUIWebViewで表示するWebページのデバッグはJSのログとか見えないので、デバッグしづらい。
その解決策はいくつかありますが、今回はJavaScriptのwindow.console.logをXCODEのコンソールに出力して、 デバッグ情報を入手しやすくする方法を紹介したいと思います。
なお以下で紹介する方法は、Stack Overflowで紹介された内容を発展させた内容となります。
JavaScriptとObjective-Cで、それぞれ以下の実装を行います。
上記で「UIWebViewの場合は」という分岐を入れる理由は、 通常だと「ios-log:#iOS#xxx」というリクエストはエラー扱いになってしまい、 その後のJavaScript実行が中止されてしまうので、それを避けるためです。
UIWebViewを利用しているか否かは、UserAgentの上書き(詳しくはこちら)などを利用して判別することが出来ます。
リクエストを補足するために、UIWebViewのDelegateを利用します。
今回はその機能を利用して、ログ出力用のリクエストの場合はキャッチして、XCODEのコンソールにログ出力をします。
JSで意図しないエラーが発生した場合(それもwondow.logを仕込んでいない箇所で)に、 ログも出ないし、画面も動かないし、何が悪いのかを特定するのが大変です。
そのため、エラー発生時のログ出力もJS側に実装するといいかと思います。
以下が実装例です。
こんな感じで少しずつでもデバッグを楽にすることが、作業の効率化に繋がるんだなぁと思っています。
より快適なデバッグ生活を求めて、これからも活動して、良き内容があればまたブログに書きたいと思います。
最後までご覧頂きましてありがとうございました。
今日は、UIWebViewベースのアプリケーションのデバッグに役立つ、 window.cosole.logの内容をXCODEのコンソールに出力する方法を書きたいと思います。
UIWebViewベースのアプリはデバッグしづらい?
UIWebViewベースのアプリを開発する際に、デバッグがしづらいという問題点があります。通常のWebページ開発では、Chromeのデベロッパーツールや、iPhone用のWebインスペクタ(詳細は、こちらを参照)を用いて開発する事で、効率的にデバッグする事が可能です。
しかしUIWebViewで表示するWebページのデバッグはJSのログとか見えないので、デバッグしづらい。
その解決策はいくつかありますが、今回はJavaScriptのwindow.console.logをXCODEのコンソールに出力して、 デバッグ情報を入手しやすくする方法を紹介したいと思います。
なお以下で紹介する方法は、Stack Overflowで紹介された内容を発展させた内容となります。
JavaScriptで出力するログをXCODEのコンソールに表示する
XCODEのコンソールにJavaScriptのwindow.console.logを出力することで、デバッグをしやすくすることが出来ます。JavaScriptとObjective-Cで、それぞれ以下の実装を行います。
- JavaScriptでXCODEでログ出力する為のリクエストを発信する。
- UIWebViewでログ出力用のリクエストを補足して、内容をコンソールに出力する。
JavaScriptでXCODEでログ出力する為のリクエストを発信する
javaScript側では、以下のように行うことで、UIWebViewに向けたリクエストを発信します。// window.console.logを上書きすると動かない場合もあるので、 // 今回は新しいメソッドを定義する。 window.log = function(msg) { // まずは通常通りのログ出力を行う。 console.log(msg); // UIWebViewを用い手居る場合には、 // XCODEのコンソールにも出力する仕組みを導入する。 if (isUIWebView && debug) { var iframe = document.createElement("IFRAME"); iframe.setAttribute("src", "ios-log:#iOS#" + msg); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; } }UIWebViewの場合は。「ios-log:#iOS#xxx」というリクエストを発信します。
上記で「UIWebViewの場合は」という分岐を入れる理由は、 通常だと「ios-log:#iOS#xxx」というリクエストはエラー扱いになってしまい、 その後のJavaScript実行が中止されてしまうので、それを避けるためです。
UIWebViewを利用しているか否かは、UserAgentの上書き(詳しくはこちら)などを利用して判別することが出来ます。
UIWebViewでログ出力用のリクエストを補足して、内容をコンソールに出力する
JavaScriptでUIWebView向けに発信したリクエストをUIWebViewで細くすることで、 リクエストに含まれるログ内容をXCODEのコンソールに出力します。リクエストを補足するために、UIWebViewのDelegateを利用します。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { // リクエストに「ios-log:#iOS#」が含まれる場合には、リクエストをキャッチする。 NSString* nextUrl=[[request URL] absoluteString]; NSRange range; if ((range=[nextUrl rangeOfString:@"ios-log:"]).location!=NSNotFound) { // リクエスト内容から、ログ内容を取得する。 NSString *iOSLog = [nextUrl stringByReplacingOccurrencesOfString:@"ios-log:"withString:@""]; // 文字列はパーセントエスケープされているので、デコードする。 iOSLog = [iOSLog stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSLog(@"%@",iOSLog); // このリクエストは、ここで中断する。 returnNO; } // 上記以外のリクエストは、そのまま発信する。 return YES; }UIWebViewDelegateの「shouldStartLoadWithRequest」のメソッドを利用することで、 実際にサーバーにリクエストを送る前に、内容を精査して中止することが出来ます。
今回はその機能を利用して、ログ出力用のリクエストの場合はキャッチして、XCODEのコンソールにログ出力をします。
エラー情報も出力する
上記でだいぶデバッグしやすくなるのですが、少し足りない。JSで意図しないエラーが発生した場合(それもwondow.logを仕込んでいない箇所で)に、 ログも出ないし、画面も動かないし、何が悪いのかを特定するのが大変です。
そのため、エラー発生時のログ出力もJS側に実装するといいかと思います。
以下が実装例です。
window.onerror = function(errMsg, url, lineNumber) { window.log(errMsg + ", file=" + url + ":" + lineNumber); }上記の実装で、エラー原因とエラー箇所がログに出力されるので、デバッグしやすくなります。
最後に
組み込みのプログラムをデバッグすることは、比較的難しい。こんな感じで少しずつでもデバッグを楽にすることが、作業の効率化に繋がるんだなぁと思っています。
より快適なデバッグ生活を求めて、これからも活動して、良き内容があればまたブログに書きたいと思います。
最後までご覧頂きましてありがとうございました。