Podczas pisania aplikacji na iPhone'a / iPada za pomocą UIWebView konsola nie jest widoczna. ta doskonała odpowiedź pokazuje, jak wychwytywać błędy, ale chciałbym również użyć console.log ().
javascript
ios
uiwebview
TinkerTank
źródło
źródło
Odpowiedzi:
Po dzisiejszej konsultacji z cenionym kolegą, poinformował mnie o Safari Developer Toolkit i o tym, jak można to połączyć z UIWebViews w symulatorze iOS w celu uzyskania danych wyjściowych z konsoli (i debugowania!).
Kroki:
[the name of your UIWebView file]
Możesz teraz upuszczać złożony (w moim przypadku flot ) JavaScript i inne rzeczy do UIWebViews i debugować do woli.
EDYCJA: Jak wskazał @Joshua J McKinnon, ta strategia działa również podczas debugowania UIWebViews na urządzeniu. Po prostu włącz Web Inspector w ustawieniach swojego urządzenia: Settings-> Safari-> Advanced-> Web Inspector (cheers @Jeremy Wiebe)
UPDATE: WKWebView jest również obsługiwany
źródło
Mam rozwiązanie do logowania za pomocą javascript do konsoli debugowania aplikacji. To trochę prymitywne, ale działa.
Najpierw definiujemy funkcję console.log () w javascript, która otwiera i natychmiast usuwa ramkę iframe z 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;
Teraz musimy przechwycić ten adres URL w UIWebViewDelegate w aplikacji iOS za pomocą funkcji 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; }
źródło
Oto rozwiązanie Swift: (trochę hackowania, aby uzyskać kontekst)
Tworzysz UIWebView.
Pobierz kontekst wewnętrzny i nadpisz funkcję 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")
źródło
JavaScriptCore
frameworka ze swoim projektem iimport
go w swoim pliku swift z przeglądarką internetową.Począwszy od iOS7, możesz używać natywnego mostka JavaScript. Coś tak prostego, jak śledzenie
#import <JavaScriptCore/JavaScriptCore.h> JSContext *ctx = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; ctx[@"console"][@"log"] = ^(JSValue * msg) { NSLog(@"JavaScript %@ log message: %@", [JSContext currentContext], msg); };
źródło
UIWebview
możesz skonfigurować dowolneJSContext
rzeczy.JSContext
nadal działa w iOS 8+ zWKWebView
?- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
i działa idealnie!WKWebView
iOS 11.4.1 i iOS, ale nie może znaleźćdocumentView
i ulega awarii. Widziałem tę odpowiedź i wydaje się, że nie jest to możliwe w ten sposób.NativeBridge jest bardzo pomocny w komunikacji z UIWebView do Objective-C. Możesz go użyć do przekazywania dzienników konsoli i wywoływania funkcji 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); };
Zaletą tej techniki jest to, że zachowywane są takie elementy, jak znaki nowego wiersza w komunikatach dziennika.
źródło
console.log
, alewindow.onerror
funkcja w tej odpowiedzi jest bardzo przydatna!Wypróbowałem rozwiązanie Leslie Godwin, ale otrzymywałem ten błąd:
'objectForKeyedSubscript' is unavailable: use subscripting
W przypadku Swift 2.2, oto co zadziałało:
Aby skompilować ten kod, musisz zaimportować JavaScriptCore:
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") }
Następnie w kodzie javascript wywołanie console.log ("_ twój_log_") zostanie wydrukowane w konsoli Xcode.
Jeszcze lepiej, dodaj ten kod jako rozszerzenie do 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") } } }
A następnie wywołaj tę metodę podczas kroku inicjalizacji UIWebView:
let webView = UIWebView(frame: CGRectZero) webView.hijackConsoleLog()
źródło
Szybki 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) } } }
źródło