Під час написання програми iPhone / iPad за допомогою UIWebView консоль не видно. ця чудова відповідь показує, як ловити помилки, але я хотів би також скористатися console.log ().
Під час написання програми iPhone / iPad за допомогою UIWebView консоль не видно. ця чудова відповідь показує, як ловити помилки, але я хотів би також скористатися console.log ().
Відповіді:
Проконсультувавшись із шанованим колегою сьогодні, він попередив мене про інструментарій розробника Safari та про те, як це можна підключити до UIWebViews в iOS Simulator для виведення консолі (та налагодження!).
Кроки:
[the name of your UIWebView file]
Тепер ви можете скидати складний (у моєму випадку, flot ) Javascript та інший матеріал в UIWebViews та налагоджувати за бажанням.
EDIT: Як зазначив @Joshua J McKinnon, ця стратегія також працює під час налагодження UIWebViews на пристрої. Просто увімкніть Web Inspector у налаштуваннях пристрою: Налаштування-> Safari-> Додатково-> Web Inspector (вітає @Jeremy Wiebe)
ОНОВЛЕННЯ: Також підтримується WKWebView
У мене є рішення увійти за допомогою 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;
}
Ось рішення Swift: (Це трохи зламати, щоб отримати контекст)
Ви створюєте 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")
JavaScriptCore
фреймворк до свого проекту та import
його у вашому швидкому файлі webview.
Починаючи з 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);
};
UIWebview
ви можете налаштувати будь-які JSContext
речі.
JSContext
все ще працює в iOS 8+ WKWebView
?
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
і воно працює чудово!
WKWebView
iOS 11.4.1, і він не може знайти documentView
і виходить з ладу. Я побачив цю відповідь, і, здається, це неможливо таким чином.
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);
};
Перевага цієї техніки полягає в тому, що такі речі, як нові рядки в повідомленнях журналу, зберігаються.
console.log
, але window.onerror
функція у цій відповіді дуже корисна!
Спробував виправити Леслі Годвін, але отримував цю помилку:
'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()