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

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

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

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

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

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

```Javascript: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としてます。

```Javascript: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を実装して
ログを吐き出しましょう

```objectivec:NativeFuncProtocol.h
#import <Foundation/Foundation.h>
@interface NativeFuncProtocol : NSURLProtocol
@end
```

```objectivec: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で用意したものを組み合わせて見ましょう

```HTML: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](https://qiita-image-store.s3.amazonaws.com/0/13729/9ac5bc5b-fe2b-aa3c-7dd3-1757e9e2548c.png "スクリーンショット 2013-08-11 3.58.50.png")

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

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

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

[XcodeColors](https://github.com/robbiehanson/XcodeColors)


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

[物置](https://github.com/jtemplej/webview-log-sample)