При написании приложения iPhone/iPad с UIWebView консоль не отображается. этот отличный ответ показывает, как ловить ошибки, но я также хотел бы использовать console.log().
Javascript console.log() в iOS UIWebView
Ответ 1
У меня есть решение для регистрации, используя javascript, в консоли отладки приложений. Это немного грубо, но оно работает.
Сначала мы определяем функцию console.log() в javascript, которая открывает и немедленно удаляет iframe с помощью 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;
Теперь мы должны поймать этот URL-адрес в UIWebViewDelegate в приложении iOS, используя функцию 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;
}
Ответ 2
После консультации с уважаемым коллегой сегодня он предупредил меня о Safari Developer Toolkit и о том, как это можно подключить к UIWebViews в iOS Simulator для вывода консоли (и отладки!).
Шаги:
- Откройте настройки Safari → вкладка "Дополнительно" → включить флажок "Показать меню" Разработка "в строке меню"
- Запустите приложение с UIWebView в iOS Simulator.
- Safari → Разработка → я (Pad/Pod) Симулятор →
[the name of your UIWebView file]
Теперь вы можете удалить сложный (в моем случае, флот) Javascript и другие вещи в UIWebViews и отлаживать по своему усмотрению.
EDIT: Как указано в @Joshua J McKinnon, эта стратегия также работает при отладке UIWebViews на устройстве. Просто включите Web Inspector в настройках вашего устройства: Настройки- > Safari- > Дополнительно- > Веб-инспектор (приветствия @Jeremy Wiebe)
UPDATE: поддерживается WKWebView
Ответ 3
Здесь быстрое решение: (Это немного взломать контекст)
-
Вы создаете UIWebView.
-
Получить внутренний контекст и переопределить функцию 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")
Ответ 4
Начиная с iOS7, вы можете использовать собственный Javascript-мост. Что-то простое, как показано ниже
#import <JavaScriptCore/JavaScriptCore.h>
JSContext *ctx = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"console"][@"log"] = ^(JSValue * msg) {
NSLog(@"JavaScript %@ log message: %@", [JSContext currentContext], msg);
};
Ответ 5
NativeBridge очень полезен для связи с UIWebView до Objective-C. Вы можете использовать его для передачи журналов консоли и вызова функций 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);
};
Преимущество этого метода в том, что такие вещи, как новые строки в сообщениях журнала, сохраняются.
Ответ 6
Пробовал исправить Лесли Годвин, но получал эту ошибку:
'objectForKeyedSubscript' is unavailable: use subscripting
Для Swift 2.2, здесь то, что сработало для меня:
Вам нужно будет импортировать 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")
}
Затем в вашем javascript-коде вызов console.log( "_ your_log_" ) будет напечатан в консоли Xcode.
Еще лучше, добавьте этот код в качестве расширения для 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")
}
}
}
И затем вызовите этот метод во время этапа инициализации UIWebView:
let webView = UIWebView(frame: CGRectZero)
webView.hijackConsoleLog()