如何從 Xcode 控制臺輸出 JavaScript 的 log?

調(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

如何從 Xcode 控制臺輸出 JavaScript 的 log?

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 官方博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容