使用 UIWebView 编写 iPhone/iPad 应用程序时,控制台不可见。 这个优秀的答案展示了如何捕获错误,但我也想使用 console.log() 。
iOS UIWebView 中的 Javascript console.log()
今天咨询了一位受人尊敬的同事后,他提醒我注意 Safari Developer Toolkit,以及如何将其连接到 iOS 模拟器中的 UIWebViews 以进行控制台输出(和调试!)。
脚步:
- 打开Safari首选项->“高级”选项卡->启用复选框“在菜单栏中显示开发菜单”
- 在 iOS 模拟器中使用 UIWebView 启动应用程序
- Safari -> 开发 -> i(Pad/Pod) 模拟器 ->
[the name of your UIWebView file]
您现在可以将复杂的(在我的情况下,是flot)Javascript 和其他内容放入 UIWebViews 并随意调试。
编辑:正如@Joshua J McKinnon 所指出的,在设备上调试 UIWebViews 时,此策略也有效。只需在您的设备设置中启用 Web Inspector:设置->Safari->高级->Web Inspector(干杯 @Jeremy Wiebe)
更新:也支持 WKWebView
我有一个使用 javascript 登录到应用程序调试控制台的解决方案。这有点粗糙,但它有效。
首先,我们在 javascript 中定义了 console.log() 函数,它打开并立即删除一个带有 ios-log: url 的 iframe。
// Debug
console = new Object();
console.log = function(log) {
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "ios-log:#iOS#" + log);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
};
console.debug = console.log;
console.info = console.log;
console.warn = console.log;
console.error = console.log;
现在我们必须使用 shouldStartLoadWithRequest 函数在 iOS 应用程序的 UIWebViewDelegate 中捕获此 URL。
- (BOOL)webView:(UIWebView *)webView2
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestString = [[[request URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
//NSLog(requestString);
if ([requestString hasPrefix:@"ios-log:"]) {
NSString* logString = [[requestString componentsSeparatedByString:@":#iOS#"] objectAtIndex:1];
NSLog(@"UIWebView console: %@", logString);
return NO;
}
return YES;
}
这是 Swift 解决方案:( 获取上下文有点麻烦)
您创建了 UIWebView。
获取内部上下文并覆盖console.log() javascript 函数。
self.webView = UIWebView() self.webView.delegate = self let context = self.webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as! JSContext let logFunction : @convention(block) (String) -> Void = { (msg: String) in NSLog("Console: %@", msg) } context.objectForKeyedSubscript("console").setObject(unsafeBitCast(logFunction, AnyObject.self), forKeyedSubscript: "log")
从 iOS7 开始,您可以使用原生 Javascript 桥接器。简单的事情如下
#import <JavaScriptCore/JavaScriptCore.h>
JSContext *ctx = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"console"][@"log"] = ^(JSValue * msg) {
NSLog(@"JavaScript %@ log message: %@", [JSContext currentContext], msg);
};
NativeBridge 对于从 UIWebView 到 Objective-C 的通信非常有帮助。您可以使用它来传递控制台日志和调用 Objective-C 函数。
https://github.com/ochameau/NativeBridge
console = new Object();
console.log = function(log) {
NativeBridge.call("logToConsole", [log]);
};
console.debug = console.log;
console.info = console.log;
console.warn = console.log;
console.error = console.log;
window.onerror = function(error, url, line) {
console.log('ERROR: '+error+' URL:'+url+' L:'+line);
};
这种技术的优点是保留了日志消息中的换行符之类的内容。