iOS UIWebView中的Javascript console.log()
使用UIWebView编写iPhone/iPad应用程序时,控制台不可见。 this excellent answer显示如何捕获错误,但我也想使用console.log()。iOS UIWebView中的Javascript console.log()
我有一个解决方案,使用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功能在UIWebViewDelegate在iOS应用此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;
}
下面看到NSTJ的简单思路。 –
这太棒了...... –
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);
};
这种技术的优点是,之类的东西在日志消息换行符将被保留。
+1。注意[Apache Cordova](http://cordova.apache.org/)用户 - Cordova已经处理'console.log',但这个答案中的'window.onerror'函数非常有用! – mpontillo
今天在咨询了一位尊敬的同事之后,他向我发送了Safari Developer Toolkit以及如何将它连接到iOS Simulator的UIWebViews以用于控制台输出(和调试!)。
步骤:
- 打开Safari偏好设置 - > “高级” 选项卡 - >启用勾选 “在菜单栏中显示开发菜单”
- 与UIWebView中开始应用在iPhone模拟器
- Safari浏览器 - >发展 - >我(PAD/POD)模拟器 - >
[the name of your UIWebView file]
现在您可以删除复杂的(在我的情况,海军报)Javascript和其他的东西进入UIWebViews并随意调试。
编辑:正如@Joshua J McKinnon所指出的,这个策略在设备上调试UIWebViews时也有效。只要在您的设备设置中启用Web检查:设置 - > Safari->高级 - > Web检查(欢呼@Jeremy韦博)
更新:支持WKWebView太
从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);
};
出于兴趣,在哪里放置这段代码的理想场所? –
好的,想通了。在创建UIWebview之后,您可以设置任何'JSContext'东西。 –
'JSContext'是否仍然可以在iOS 8+中使用WKWebView? –
简单以下是雨燕的解决方案: (这是一个黑客位来获取上下文)
您创建一个UIWebView。
-
获取内部上下文并覆盖控制台上的。日志() 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")
+100!节省了我吨的时间,很好的黑客,需要在JS代码中进行0次更改。谢谢!!就我未来的读者而言,我的2美分:不要忘记将JavaScriptCore框架链接到您的项目并将它导入到您的webview swift文件中。 – mindbomb
太棒了!谢谢! – Frade
不适用于WKWebView :-( – CedricSoubrie
试图莱斯利·戈德温的修复,但在收到此错误:
'objectForKeyedSubscript' is unavailable: use subscripting
对于雨燕2.2,这里是为我工作:
您需要导入的JavaScriptCore此代码编译:
import JavaScriptCore
if let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") {
context.evaluateScript("var console = { log: function(message) { _consoleLog(message) } }")
let consoleLog: @convention(block) String -> Void = { message in
print("javascript_log: " + message)
}
context.setObject(unsafeBitCast(consoleLog, AnyObject.self), forKeyedSubscript: "_consoleLog")
}
然后在你的javascript代码中,调用console.log(“_ your_log_”)将在Xcode控制台中打印。
更重要的是,添加以下代码作为扩展的UIWebView:
import JavaScriptCore
extension UIWebView {
public func hijackConsoleLog() {
if let context = valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") {
context.evaluateScript("var console = { log: function(message) { _consoleLog(message) } }")
let consoleLog: @convention(block) String -> Void = { message in
print("javascript_log: " + message)
}
context.setObject(unsafeBitCast(consoleLog, AnyObject.self), forKeyedSubscript: "_consoleLog")
}
}
}
然后在你的UIWebView初始化步骤调用这个方法:
let webView = UIWebView(frame: CGRectZero)
webView.hijackConsoleLog()
写在浏览器中第一次,开启开发工具,然后看看控制台输出。 – tjameson