LoginSignup
14
13

More than 5 years have passed since last update.

UIWebViewのデバッグ効率を少しでもあげる方法(Log編)

Last updated at Posted at 2013-08-10

iOS6からはWebインスペクタを使用してJSのデバッグできますが
iOS5に関してはWebインスペクタ使えないんでJSのデバッグきついです。。。

せめてconsole.logの内容をx-codeから確認したい!

ということで以下の手順でログを出力しましょう。

用意するもの
・jquery
・NSURLProtocol
・jsファイル(app.js、native-func.js)
・html

1.console.logを置き換えよう
どうせならconsole.logを実行したタイミングで特に何もせずに
出力したいので置き換えましょう。

app.js
if (!window.App) App = {};
App.Native = {};

if(typeof $ !== "undefined") {
    // ios6のキャッシュ対策.
    $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
        options.data = jQuery.param($.extend(originalOptions.data||{}, {
            timeStamp: new Date().getTime()
        }));
    });
}

// console.logの置き換え.
console.log_org = console.log;
console.log = function(message){
    App.Native.log(message);
    return console.log_org.apply(this, arguments);
}

2.log出力用のjsを用意する
ログ出力用のURLとパラメータを決めてそれをgetで読み込ませましょう。
今回はURLを「native-func/log」、パラメータをmessageとしてます。

native-func.js
App.Native = (function($) {
    var _log = function(message) {
        message = encodeURIComponent(message);
        $.get('/native-func/log?message=' + message);
    };
    return {
        log:_log
    };
}(jQuery));

3.native側でログ用の命令を処理しよう
NSURLProtocolを継承して独自のProtocolを実装して
ログを吐き出しましょう

NativeFuncProtocol.h
#import <Foundation/Foundation.h>
@interface NativeFuncProtocol : NSURLProtocol
@end
NativeFuncProtocol.m
#import "NativeFuncProtocol.h"

static NSString* const NATIVE_FUNC_IDENTIFIER = @"native-func";

@implementation NativeFuncProtocol

+(BOOL) canInitWithRequest:(NSURLRequest *)request {
    NSArray* pathComponents = request.URL.pathComponents;
    // ログ出力の場合はこのProtocolで処理する.
    if(pathComponents.count == 3 && [pathComponents[1] isEqualToString:NATIVE_FUNC_IDENTIFIER]){
        return YES;
    }
    return NO;
}

+(NSURLRequest*) canonicalRequestForRequest:(NSURLRequest *)request {
    return request;
}

-(void) startLoading {
    NSArray* pathComponents = self.request.URL.pathComponents;
    if(pathComponents.count == 3 && [pathComponents[2] isEqualToString:@"log"]) {
        NSArray* param = [self.request.URL.query componentsSeparatedByString:@"&"];
        NSArray* messageParam = [param[0] componentsSeparatedByString:@"="];
        NSString* message = [self urlDecode:messageParam.lastObject];

        // ログ出力.
        NSLog(@"WebLog %@", message);

        NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[self.request URL]
                                                                  statusCode:200
                                                                 HTTPVersion:@"1.1"
                                                                headerFields:nil];
        [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
        [self.client URLProtocol:self didLoadData:nil];
        [self.client URLProtocolDidFinishLoading:self];
    }
}

-(void) stopLoading {
}

-(NSString*) urlDecode:(NSString*)url {
    return (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(
        kCFAllocatorDefault,
        (__bridge CFStringRef)url,
        CFSTR(""),
        kCFStringEncodingUTF8);
}
@end

4.1-3で用意したものを組み合わせて見ましょう

empty.html
<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <title>TEST</title>
  <script src="jquery-2.0.3.min.js"></script>
  <script src="app.js"></script>
  <script src="native-func.js"></script>
</head>
<body>
<div id="log-button">Log出すよ.</div>
<script>
    $(function(){
      $("#log-button").on("click", function(){
          console.log("ログ出力するよー");
      });
    });
</script>
</body>
</html>

5.x-codeのdebug consoleを確認してみよう
無事に出ましたね(2回出てるのは2回押したからです。。。)

スクリーンショット 2013-08-11 3.58.50.png

今回のコードは特にセキュリティとか、意図してないパラメータは考慮してませんので、実際使う場合はきちんとその辺りをきれいにしてください。

これで多少はデバッグ効率があがると思います。

あとは既存のNative側のログとWebからのLogを見やすくするために
プラグインやLibraryを入れて対応するとさらによくなると思います。
私の環境ではXcodecolors入れてログの可読性をあげてます。

XcodeColors

最後に今回のProjectをあげておきますので
よろしければ色々触ってみてください。

物置

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13