iOS UIWebView中的Javascript console.log()




xcode javascript (4)

在使用UIWebView编写iPhone / iPad应用程序时,控制台不可见。 这个优秀的答案显示了如何捕获错误,但我也想使用console.log()。

https://code.i-harness.com


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);
};

这种技术的优点是保留了日志消息中的换行符等内容。


以下是Swift解决方案:( 获取上下文有点麻烦)

  1. 你创建UIWebView。

  2. 获取内部上下文并覆盖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);
    };

我有一个解决方案,使用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;
}




uiwebview