Ao escrever um aplicativo para iPhone / iPad com UIWebView, o console não fica visível. esta excelente resposta mostra como interceptar erros, mas eu gostaria de usar o console.log () também.
javascript
ios
uiwebview
TinkerTank
fonte
fonte
Respostas:
Depois de consultar um estimado colega hoje, ele me alertou sobre o Safari Developer Toolkit e como ele pode ser conectado a UIWebViews no simulador iOS para saída de console (e depuração!).
Passos:
[the name of your UIWebView file]
Agora você pode colocar Javascript complexo (no meu caso, flot ) e outras coisas em UIWebViews e depurar à vontade.
EDIT: Como apontado por @Joshua J McKinnon, essa estratégia também funciona ao depurar UIWebViews em um dispositivo. Basta habilitar o Web Inspector nas configurações do seu dispositivo: Configurações-> Safar-> Avançado-> Web Inspector (elogios @Jeremy Wiebe)
ATUALIZAÇÃO: WKWebView também é compatível
fonte
Eu tenho uma solução para fazer login, usando javascript, no console de depuração de aplicativos. É um pouco grosseiro, mas funciona.
Primeiro, definimos a função console.log () em javascript, que abre e remove imediatamente um iframe com um 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;
Agora temos que capturar esse URL no UIWebViewDelegate no aplicativo iOS usando a função 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; }
fonte
Esta é a solução do Swift: (é um pouco um hack para obter o contexto)
Você cria o UIWebView.
Obtenha o contexto interno e substitua a função 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")
fonte
JavaScriptCore
framework ao seu projeto eimport
ele em seu arquivo swift do webview.A partir do iOS7, você pode usar a ponte Javascript nativa. Algo tão simples 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); };
fonte
UIWebview
você pode configurar qualquerJSContext
coisa.JSContext
ainda funciona em iOS 8+ comWKWebView
?- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
e funciona perfeitamente!WKWebView
iOS 11.4.1 e ele não consegue encontrardocumentView
e trava. Eu vi essa resposta e parece que não é possível assim.NativeBridge é muito útil para a comunicação de um UIWebView para Objective-C. Você pode usá-lo para passar logs de console e chamar funções 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); };
A vantagem dessa técnica é que coisas como novas linhas nas mensagens de log são preservadas.
fonte
console.log
, mas awindow.onerror
função nesta resposta é muito útil!Tentei a correção de Leslie Godwin, mas estava obtendo este erro:
'objectForKeyedSubscript' is unavailable: use subscripting
Para Swift 2.2, aqui está o que funcionou para mim:
Você precisará importar JavaScriptCore para este código compilar:
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") }
Em seguida, em seu código javascript, chamar console.log ("_ your_log_") imprimirá no console Xcode.
Melhor ainda, adicione este código como uma extensão para 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") } } }
Em seguida, chame este método durante a etapa de inicialização do UIWebView:
let webView = UIWebView(frame: CGRectZero) webView.hijackConsoleLog()
fonte
Swift 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) } } }
fonte