調(diào)試 UIWebView 中的 JavaScript 一直以來都是很痛苦的一件事。通常我們會(huì)通過下面的方法調(diào)試 HTML 和 JavaScript。
1、第一種,使用桌面瀏覽器調(diào)試。大多數(shù)現(xiàn)代瀏覽器都有功能強(qiáng)大的調(diào)試器,可以通過 console.log() 方法進(jìn)行調(diào)試。
2、如果桌面瀏覽器不能追蹤到這些 log,我們可以從 Xcode 啟動(dòng) iOS 模擬器,運(yùn)行我們的 app。然后,啟動(dòng) Safari 選擇 Develop > iPhone Simulator > tieba.baidu.com

3.如果你不能在 iOS 模擬器上復(fù)現(xiàn)問題,也不能從運(yùn)行在 iPhone 真機(jī)上的 APP 獲得 console.log(),要調(diào)試 HTML 或者 JavaScript 是非常困難的。這篇文章就教你怎么用 NSLog 輸出 JavaScript 中的 log。
把 JavaScript Log 轉(zhuǎn)化成 Application Log
最基本的思路是這樣的:為了把 JavaScript 的 log 現(xiàn)實(shí)出來,我們需要給debugger 發(fā)出一個(gè) XMLHttpRequest,發(fā)起一個(gè)特殊的請求,把 Log 信息當(dāng)做請求的路徑,debugger 當(dāng)做 host 名,例如: http://debugger/myError。我們可以通過 Apple 提供給我們的黑科技 NSURLProtocl 截獲所有從 UIWebView 發(fā)起的請求。如果請求里有 「debugger」,就是用 NSURLProtocol 調(diào)用 NSLog 打印這些 log。
假設(shè)你的工程里有一個(gè)文件叫做 Sample.html
<html>
<head>
<script>
function log(msg) {
var xhr = new XMLHttpRequest();
xhr.open('GET', "http://debugger/" +
encodeURIComponent(msg));
xhr.send(null);
}
function test() {
log("Button was clicked");
log("We are done");
return false;
}
</script>
</head>
<body>
<button onclick="return test();">Click Me</button>
</body>
</html>
接下來,創(chuàng)建一個(gè) NSURLProtocol 的子類 WebConsole
/WebConsole.h
@interface WebConsole : NSURLProtocol
+ (void) enable;
@end
//WebConsole.m
@implementation WebConsole
+ (void) enable {
[NSURLProtocol registerClass:[WebConsole class]];
}
+ (BOOL) canInitWithRequest:(NSURLRequest *)request {
if ([[[request URL] host] isEqualToString:@"debugger"]){
NSLog(@"%@", [[[request URL] path] substringFromIndex: 1]);
}
return FALSE;
}
@end
通過 canInitWithRequest 檢查截獲的請求,如果請求的 host 是「debugger」就用 NSLog 把這個(gè)請求的 「path」(也就是 JavaScript 的 log)輸出。
最后我們只需要在 UIWebView 加載請求之前調(diào)用 enable,注冊這個(gè)類,就能夠通過攔截 UIWebView 發(fā)起的請求打印 JavaScript 的 log 了。
- (void)viewDidLoad {
[super viewDidLoad];
[WebConsole enable];
NSError *error = nil;
NSString *htmlStr = [NSString stringWithContentsOfFile:
[[NSBundle mainBundle]
pathForResource:@"Sample" ofType:@"html"]
encoding:NSUTF8StringEncoding
error:&error];
[self.webView loadHTMLString:htmlStr baseURL:nil];
}
OneAPM Mobile Insight 以真實(shí)用戶體驗(yàn)為度量標(biāo)準(zhǔn)進(jìn)行 Crash 分析,監(jiān)控網(wǎng)絡(luò)請求及網(wǎng)絡(luò)錯(cuò)誤,提升用戶留存。訪問 OneAPM 官方網(wǎng)站感受更多應(yīng)用性能優(yōu)化體驗(yàn),想閱讀更多技術(shù)文章,請?jiān)L問 OneAPM 官方技術(shù)博客。
本文轉(zhuǎn)自 OneAPM 官方博客