Lors de l'écriture d'une application iPhone / iPad avec une UIWebView, la console n'est pas visible. cette excellente réponse montre comment piéger les erreurs, mais j'aimerais aussi utiliser console.log ().
javascript
ios
uiwebview
TinkerTank
la source
la source
Réponses:
Après avoir consulté un collègue estimé aujourd'hui, il m'a alerté sur Safari Developer Toolkit, et comment cela peut être connecté à UIWebViews dans le simulateur iOS pour la sortie de la console (et le débogage!).
Pas:
[the name of your UIWebView file]
Vous pouvez maintenant déposer du Javascript complexe (dans mon cas, flot ) et d'autres éléments dans UIWebViews et déboguer à volonté.
EDIT: Comme l'a souligné @Joshua J McKinnon, cette stratégie fonctionne également lors du débogage d'UIWebViews sur un appareil. Activez simplement l'inspecteur Web sur les paramètres de votre appareil: Paramètres-> Safari-> Avancé-> Inspecteur Web (bravo @Jeremy Wiebe)
MISE À JOUR: WKWebView est également pris en charge
la source
J'ai une solution pour me connecter, en utilisant javascript, à la console de débogage des applications. C'est un peu grossier, mais ça marche.
Tout d'abord, nous définissons la fonction console.log () en javascript, qui ouvre et supprime immédiatement un iframe avec 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;
Nous devons maintenant attraper cette URL dans UIWebViewDelegate dans l'application iOS à l'aide de la fonction 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; }
la source
Voici la solution Swift: (C'est un peu un hack pour obtenir le contexte)
Vous créez l'UIWebView.
Obtenez le contexte interne et remplacez la fonction 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")
la source
JavaScriptCore
framework à votre projet etimport
celui - ci dans votre fichier webview swift.À partir d'iOS7, vous pouvez utiliser le pont Javascript natif. Quelque chose d'aussi simple que de suivre
#import <JavaScriptCore/JavaScriptCore.h> JSContext *ctx = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; ctx[@"console"][@"log"] = ^(JSValue * msg) { NSLog(@"JavaScript %@ log message: %@", [JSContext currentContext], msg); };
la source
UIWebview
vous pouvez configurer n'importe quel élémentJSContext
.JSContext
toujours sous iOS 8+ avecWKWebView
?- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
et ça marche parfaitement!WKWebView
et iOS 11.4.1 et il ne trouve pasdocumentView
et plante. J'ai vu cette réponse et il semble que ce n'est pas possible de cette façon.NativeBridge est très utile pour communiquer depuis une UIWebView vers Objective-C. Vous pouvez l'utiliser pour transmettre les journaux de la console et appeler les fonctions 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); };
L'avantage de cette technique est que des éléments tels que les retours à la ligne dans les messages de journal sont conservés.
la source
console.log
, mais lawindow.onerror
fonction dans cette réponse est très utile!J'ai essayé le correctif de Leslie Godwin mais obtenait cette erreur:
'objectForKeyedSubscript' is unavailable: use subscripting
Pour Swift 2.2, voici ce qui a fonctionné pour moi:
Vous devrez importer JavaScriptCore pour que ce code soit compilé:
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") }
Ensuite, dans votre code javascript, l'appel de console.log ("_ votre_log_") s'imprimera dans la console Xcode.
Mieux encore, ajoutez ce code en tant qu'extension à 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") } } }
Et puis appelez cette méthode lors de votre étape d'initialisation UIWebView:
let webView = UIWebView(frame: CGRectZero) webView.hijackConsoleLog()
la source
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) } } }
la source