iOS UIWebView의 Javascript console.log ()
UIWebView로 iPhone / iPad 앱을 작성할 때 콘솔이 표시되지 않습니다. 이 훌륭한 대답 은 오류를 포착하는 방법을 보여 주지만 console.log ()도 사용하고 싶습니다.
오늘 존경받는 동료와상의 한 후 그는 Safari 개발자 툴킷에 대해 알려 주었고, 콘솔 출력 (및 디버깅!)을 위해 iOS 시뮬레이터의 UIWebViews에 어떻게 연결할 수 있는지 알려주었습니다.
단계 :
- Safari 환경 설정 열기-> "고급"탭-> "메뉴 막대에 개발 메뉴 표시"확인란을 활성화합니다.
- iOS 시뮬레이터에서 UIWebView로 앱 시작
- Safari-> 개발-> i (Pad / Pod) 시뮬레이터->
[the name of your UIWebView file]
이제 복잡한 (제 경우에는 flot ) Javascript 및 기타 항목을 UIWebViews에 드롭 하고 원하는대로 디버그 할 수 있습니다.
편집 : @Joshua J McKinnon이 지적했듯이이 전략은 장치에서 UIWebView를 디버깅 할 때도 작동합니다. 장치 설정에서 Web Inspector를 활성화하기 만하면됩니다 : Settings-> Safari-> Advanced-> Web Inspector (@Jeremy Wiebe 건배)
업데이트 : WKWebView도 지원됩니다.
자바 스크립트를 사용하여 앱 디버그 콘솔에 로깅하는 솔루션이 있습니다. 약간 조잡하지만 작동합니다.
먼저 ios-log : url로 iframe을 열고 즉시 제거하는 javascript에서 console.log () 함수를 정의합니다.
// 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;
이제 shouldStartLoadWithRequest 함수를 사용하여 iOS 앱의 UIWebViewDelegate에서이 URL을 포착해야합니다.
- (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를 만듭니다.
내부 컨텍스트를 가져오고 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")
Starting from iOS7, you can use native Javascript bridge. Something as simple as following
#import <JavaScriptCore/JavaScriptCore.h>
JSContext *ctx = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"console"][@"log"] = ^(JSValue * msg) {
NSLog(@"JavaScript %@ log message: %@", [JSContext currentContext], msg);
};
NativeBridge is very helpful for communicating from a UIWebView to Objective-C. You can use it to pass console logs and call Objective-C functions.
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);
};
The advantage of this technique is that things like newlines in log messages are preserved.
Tried Leslie Godwin's fix but was getting this error:
'objectForKeyedSubscript' is unavailable: use subscripting
For Swift 2.2, here's what worked for me:
You will need to import JavaScriptCore for this code to compile:
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")
}
Then in your javascript code, calling console.log("_your_log_") will print in Xcode console.
Better yet, add this code as an extension to 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")
}
}
}
And then call this method during your UIWebView initialization step:
let webView = UIWebView(frame: CGRectZero)
webView.hijackConsoleLog()
참고URL : https://stackoverflow.com/questions/6508313/javascript-console-log-in-an-ios-uiwebview
'your programing' 카테고리의 다른 글
문자열에서 처음 10자를 제거하는 방법은 무엇입니까? (0) | 2020.10.08 |
---|---|
"off"상태에서 UISwitch의 색상 변경 (0) | 2020.10.08 |
경고 : DOMDocument :: loadHTML () : htmlParseEntityRef : ';'예상 (0) | 2020.10.08 |
Java-지정된 길이와 특정 문자로 채워진 새 문자열 인스턴스를 만듭니다. (0) | 2020.10.08 |
중심점을 기준으로 한 Android 이미지 배율 애니메이션 (0) | 2020.10.08 |