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 ().
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 ().
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
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;
}
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")
JavaScriptCore
framework à votre projet et import
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);
};
UIWebview
vous pouvez configurer n'importe quel élément JSContext
.
JSContext
toujours sous iOS 8+ avec WKWebView
?
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
et ça marche parfaitement!
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.
console.log
, mais la window.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()