Khi viết ứng dụng iPhone / iPad bằng UIWebView, bảng điều khiển sẽ không hiển thị. câu trả lời tuyệt vời này chỉ ra cách bẫy lỗi, nhưng tôi cũng muốn sử dụng console.log ().
Khi viết ứng dụng iPhone / iPad bằng UIWebView, bảng điều khiển sẽ không hiển thị. câu trả lời tuyệt vời này chỉ ra cách bẫy lỗi, nhưng tôi cũng muốn sử dụng console.log ().
Câu trả lời:
Sau khi tham khảo ý kiến của một đồng nghiệp đáng kính, hôm nay anh ấy đã cảnh báo tôi về Bộ công cụ dành cho nhà phát triển Safari và cách kết nối bộ công cụ này với UIWebViews trong Trình mô phỏng iOS cho đầu ra bảng điều khiển (và gỡ lỗi!).
Các bước:
[the name of your UIWebView file]
Bây giờ bạn có thể thả Javascript phức tạp (trong trường hợp của tôi là flot ) và những thứ khác vào UIWebViews và gỡ lỗi theo ý muốn.
CHỈNH SỬA: Như đã chỉ ra bởi @Joshua J McKinnon, chiến lược này cũng hoạt động khi gỡ lỗi UIWebViews trên một thiết bị. Chỉ cần bật Trình kiểm tra web trên cài đặt thiết bị của bạn: Cài đặt-> Safari-> Nâng cao-> Trình kiểm tra web (chúc mừng @Jeremy Wiebe)
CẬP NHẬT: WKWebView cũng được hỗ trợ
Tôi có một giải pháp để ghi nhật ký, sử dụng javascript, vào bảng điều khiển gỡ lỗi ứng dụng. Nó hơi thô, nhưng nó hoạt động.
Đầu tiên, chúng ta xác định hàm console.log () trong javascript, hàm này sẽ mở và xóa ngay lập tức một iframe có 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;
Bây giờ chúng ta phải bắt URL này trong UIWebViewDelegate trong ứng dụng iOS bằng cách sử dụng chức năng 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;
}
Đây là giải pháp Swift: (Có một chút khó khăn khi lấy bối cảnh)
Bạn tạo UIWebView.
Lấy ngữ cảnh bên trong và ghi đè hàm 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
khung với dự án của bạn và import
nó trong tệp nhanh webview của bạn.
Bắt đầu từ iOS7, bạn có thể sử dụng cầu nối Javascript gốc. Một cái gì đó đơn giản như sau
#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
bạn có thể thiết lập bất kỳ JSContext
thứ gì.
JSContext
vẫn làm việc trong iOS 8+ với WKWebView
?
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
và nó hoạt động hoàn hảo!
WKWebView
iOS 11.4.1 và anh ấy không thể tìm thấy documentView
và bị lỗi. Tôi đã thấy câu trả lời này và có vẻ như không thể theo cách này.
NativeBridge rất hữu ích để giao tiếp từ UIWebView sang Objective-C. Bạn có thể sử dụng nó để chuyển các bản ghi bảng điều khiển và gọi các hàm 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);
};
Ưu điểm của kỹ thuật này là những thứ như dòng mới trong thông báo nhật ký được giữ nguyên.
console.log
, nhưng window.onerror
chức năng trong câu trả lời này rất hữu ích!
Đã thử sửa lỗi của Leslie Godwin nhưng gặp lỗi này:
'objectForKeyedSubscript' is unavailable: use subscripting
Đối với Swift 2.2, đây là những gì phù hợp với tôi:
Bạn sẽ cần nhập JavaScriptCore cho mã này để biên dịch:
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")
}
Sau đó, trong mã javascript của bạn, việc gọi console.log ("_ your_log_") sẽ in trong bảng điều khiển Xcode.
Tốt hơn, hãy thêm mã này làm tiện ích mở rộng cho 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")
}
}
}
Và sau đó gọi phương thức này trong bước khởi tạo UIWebView của bạn:
let webView = UIWebView(frame: CGRectZero)
webView.hijackConsoleLog()