เมื่อเขียนแอพ iPhone / iPad ด้วย UIWebView คอนโซลจะมองไม่เห็น คำตอบที่ยอดเยี่ยมนี้แสดงวิธีดักจับข้อผิดพลาด แต่ฉันต้องการใช้ console.log () ด้วย
เมื่อเขียนแอพ iPhone / iPad ด้วย UIWebView คอนโซลจะมองไม่เห็น คำตอบที่ยอดเยี่ยมนี้แสดงวิธีดักจับข้อผิดพลาด แต่ฉันต้องการใช้ console.log () ด้วย
คำตอบ:
หลังจากปรึกษากับเพื่อนร่วมงานที่นับถือแล้ววันนี้เขาแจ้งเตือนฉันถึง Safari Developer Toolkit และวิธีนี้จะเชื่อมต่อกับ UIWebViews ใน iOS Simulator สำหรับเอาต์พุตคอนโซล (และการดีบัก!)
ขั้นตอน:
[the name of your UIWebView file]
ตอนนี้คุณสามารถวางJavascript ที่ซับซ้อน (ในกรณีของฉันคือflot ) และสิ่งอื่น ๆ ลงใน UIWebViews และดีบักได้ตามต้องการ
แก้ไข: ตามที่ระบุไว้โดย @Joshua J McKinnon กลยุทธ์นี้ยังใช้งานได้เมื่อดีบัก UIWebViews บนอุปกรณ์ เพียงเปิดใช้งาน Web Inspector ในการตั้งค่าอุปกรณ์ของคุณ: การตั้งค่า -> Safari-> ขั้นสูง -> Web Inspector (ไชโย @Jeremy Wiebe)
อัปเดต: รองรับ WKWebView ด้วย
ฉันมีวิธีการบันทึกโดยใช้จาวาสคริปต์ไปยังคอนโซลการดีบักของแอป มันค่อนข้างหยาบ แต่ใช้งานได้
ขั้นแรกเรากำหนดฟังก์ชัน 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
ในไฟล์ swift webview ของคุณ
เริ่มจาก iOS7 คุณสามารถใช้ Javascript bridge สิ่งง่ายๆดังต่อไปนี้
#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
และมันก็ทำงานได้อย่างสมบูรณ์แบบ!
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
ฟังก์ชันในคำตอบนี้มีประโยชน์มาก!
พยายามแก้ไขของ Leslie Godwin แต่ได้รับข้อผิดพลาดนี้:
'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")
}
จากนั้นในโค้ดจาวาสคริปต์ของคุณการเรียก 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()
สวิฟต์ 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)
}
}
}