88 votes

Javascript console.log() dans un UIWebView iOS

Lorsque l'on écrit une application iPhone / iPad avec un UIWebView, la console n'est pas visible. cette excellente réponse montre comment piéger les erreurs, mais j'aimerais aussi utiliser la fonction console.log().

1 votes

Écrivez-le d'abord dans le navigateur, activez les outils de développement, puis regardez la sortie de la console.

195voto

NSTJ Points 972

Après avoir consulté un collègue estimé aujourd'hui, il m'a informé de l'existence du Safari Developer Toolkit et de la manière dont il peut être connecté aux UIWebViews dans le simulateur iOS pour une sortie console (et un débogage !).

Des pas :

  1. Ouvrez les préférences de Safari -> onglet "Avancé" -> activez la case à cocher "Afficher le menu Développer dans la barre de menu".
  2. Démarrer une application avec UIWebView dans le simulateur iOS
  3. Safari -> Développer -> Simulateur i(Pad/Pod) -> [the name of your UIWebView file]

Vous pouvez maintenant déposer des complexes (dans mon cas, flot ) Javascript et autres dans les UIWebViews et déboguer à volonté.

EDIT : Comme l'a souligné @Joshua J McKinnon, cette stratégie fonctionne également lors du débogage des UIWebViews sur un appareil. Il suffit d'activer l'inspecteur Web dans les paramètres de votre appareil : Paramètres->Safari->Avancé->Inspecteur Web (merci @Jeremy Wiebe)

MISE À JOUR : WKWebView est également pris en charge.

13 votes

Notez que cette stratégie fonctionne également lors du débogage sur des appareils iOS réels.

2 votes

+100 si je pouvais. C'est merveilleux, ça marche aussi pour les applis d'écart de téléphone !

0 votes

Il faudrait en faire la réponse. C'est merveilleux et je suis d'accord avec ce qui précède, cela devrait obtenir tous les votes positifs.

82voto

TumbleCow Points 1931

J'ai une solution pour enregistrer, à l'aide de javascript, dans la console de débogage de l'application. C'est un peu rudimentaire, mais ça fonctionne.

Tout d'abord, nous définissons la fonction console.log() en javascript, qui ouvre et supprime immédiatement une iframe avec une url ios-log :.

// 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 le UIWebViewDelegate de l'application iOS en utilisant 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;
}

1 votes

Voir l'idée simple de NSTJ ci-dessous.

0 votes

Dans swift 4 peut-être ? :D

37voto

Leslie Godwin Points 258

Voici la solution Swift : (C'est un peu un hack pour avoir le contexte)

  1. Vous créez le UIWebView.

  2. Obtenez le contexte interne et remplacez la fonction console.log() fonction 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")

28voto

Ji Fang Points 671

À partir d'iOS7, vous pouvez utiliser la passerelle Javascript native. 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);
    };

9voto

tangent405 Points 41

NativeBridge est très utile pour communiquer d'un UIWebView vers Objective-C. Vous pouvez l'utiliser pour transmettre les journaux de la console et appeler des 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 nouvelles lignes dans les messages du journal sont préservés.

0 votes

+1. Note à Apache Cordova les utilisateurs - Cordova gère déjà console.log mais le window.onerror dans cette réponse est très utile !

0 votes

Pour les développeurs Appcelerator/Titanium : cela fonctionne aussi pour déboguer votre Ti.UI.WebView.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X