Al escribir una aplicación para iPhone / iPad con UIWebView, la consola no está visible. esta excelente respuesta muestra cómo atrapar errores, pero también me gustaría usar console.log ().
javascript
ios
uiwebview
TinkerTank
fuente
fuente
Respuestas:
Después de consultar con un estimado colega hoy, me alertó sobre Safari Developer Toolkit, y cómo esto se puede conectar a UIWebViews en el simulador de iOS para la salida de la consola (¡y la depuración!).
Pasos:
[the name of your UIWebView file]
Ahora puede colocar Javascript complejo (en mi caso, flot ) y otras cosas en UIWebViews y depurar a voluntad.
EDITAR: Como lo señaló @Joshua J McKinnon, esta estrategia también funciona al depurar UIWebViews en un dispositivo. Simplemente habilite Web Inspector en la configuración de su dispositivo: Configuración-> Safari-> Avanzado-> Web Inspector (salud @Jeremy Wiebe)
ACTUALIZACIÓN: WKWebView también es compatible
fuente
Tengo una solución para iniciar sesión, usando javascript, en la consola de depuración de aplicaciones. Es un poco tosco, pero funciona.
Primero, definimos la función console.log () en javascript, que abre y elimina inmediatamente un iframe con un ios-log: url.
// 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;
Ahora tenemos que capturar esta URL en UIWebViewDelegate en la aplicación de iOS usando la función shouldStartLoadWithRequest.
- (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; }
fuente
Aquí está la solución Swift: (es un truco para obtener el contexto)
Creas el UIWebView.
Obtenga el contexto interno y anule la función de JavaScript console.log () .
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")
fuente
JavaScriptCore
marco a su proyecto yimport
en su archivo rápido de webview.A partir de iOS7, puede utilizar el puente Javascript nativo. Algo tan simple como seguir
#import <JavaScriptCore/JavaScriptCore.h> JSContext *ctx = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; ctx[@"console"][@"log"] = ^(JSValue * msg) { NSLog(@"JavaScript %@ log message: %@", [JSContext currentContext], msg); };
fuente
UIWebview
, puede configurar cualquier elementoJSContext
.JSContext
Sigue funcionando en iOS 8+ conWKWebView
?- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
y funciona perfectamente!WKWebView
iOS 11.4.1 y no puede encontrarlodocumentView
y se bloquea. Vi esta respuesta y parece que no es posible de esta manera.NativeBridge es muy útil para comunicarse desde UIWebView a Objective-C. Puede usarlo para pasar registros de la consola y llamar a funciones de 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); };
La ventaja de esta técnica es que se conservan elementos como las líneas nuevas en los mensajes de registro.
fuente
console.log
, ¡pero lawindow.onerror
función en esta respuesta es muy útil!Probé la solución de Leslie Godwin pero recibí este error:
'objectForKeyedSubscript' is unavailable: use subscripting
Para Swift 2.2, esto es lo que funcionó para mí:
Necesitará importar JavaScriptCore para que este código se compile:
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") }
Luego, en su código javascript, al llamar a console.log ("_ your_log_") se imprimirá en la consola de Xcode.
Mejor aún, agregue este código como una extensión a 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") } } }
Y luego llame a este método durante el paso de inicialización de UIWebView:
let webView = UIWebView(frame: CGRectZero) webView.hijackConsoleLog()
fuente
Rápido 5
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { webView.evaluateJavaScript("your javascript string") { (value, error) in if let errorMessage = (error! as NSError).userInfo["WKJavaScriptExceptionMessage"] as? String { print(errorMessage) } } }
fuente