UIWebView के साथ iPhone / iPad ऐप लिखते समय, कंसोल दिखाई नहीं देता है। यह उत्कृष्ट उत्तर यह दिखाता है कि त्रुटियों को कैसे फँसाया जाए, लेकिन मैं साथ ही कंसोल.लॉग () का उपयोग करना चाहूंगा।
UIWebView के साथ iPhone / iPad ऐप लिखते समय, कंसोल दिखाई नहीं देता है। यह उत्कृष्ट उत्तर यह दिखाता है कि त्रुटियों को कैसे फँसाया जाए, लेकिन मैं साथ ही कंसोल.लॉग () का उपयोग करना चाहूंगा।
जवाबों:
एक सम्मानित सहयोगी के साथ परामर्श करने के बाद आज उन्होंने मुझे सफारी डेवलपर टूलकिट के लिए सतर्क किया, और यह कंसोल आउटपुट (और डिबगिंग!) के लिए iOS सिम्युलेटर में UIWebViews से कैसे जुड़ा जा सकता है।
कदम:
[the name of your UIWebView file]अब आप जटिल (मेरे मामले में, फ़्लोट ) जावास्क्रिप्ट और अन्य सामान को UIWebViews में छोड़ सकते हैं और अपनी इच्छानुसार डिबग कर सकते हैं।
EDIT: जैसा कि @Joshua J McKinnon ने बताया कि यह रणनीति तब भी काम करती है जब किसी डिवाइस पर UIWebViews को डीबग करता है। बस अपने डिवाइस सेटिंग्स पर वेब इंस्पेक्टर को सक्षम करें: सेटिंग्स-> सफारी-> उन्नत-> वेब इंस्पेक्टर (चीयर्स @ जेरेमी होई)
अद्यतन: WKWebView भी समर्थित है
मेरे पास ऐप्स डिबग कंसोल के लिए जावास्क्रिप्ट का उपयोग करके लॉग इन करने का समाधान है। यह थोड़ा कच्चा है, लेकिन यह काम करता है।
सबसे पहले, हम जावास्क्रिप्ट में कंसोल.लॉग () फ़ंक्शन को परिभाषित करते हैं, जो खोलता है और तुरंत एक आईओएस-लॉग: यूआरएल के साथ एक आइफ्रेम निकालता है।
// 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;
अब हमें इस यूआरएल को 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;
}
यहाँ स्विफ्ट समाधान है: (यह संदर्भ प्राप्त करने के लिए एक हैक का एक सा है)
आप UIWebView बनाएं।
आंतरिक संदर्भ प्राप्त करें और कंसोल.लॉग () जावास्क्रिप्ट फ़ंक्शन को ओवरराइड करें ।
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यह आपके वेबव्यू स्विफ्ट फाइल में है।
IOS7 से शुरू होकर, आप देशी जावास्क्रिप्ट ब्रिज का उपयोग कर सकते हैं। निम्नलिखित के रूप में कुछ सरल है
#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 से ऑब्जेक्टिव-सी तक संचार करने के लिए बहुत सहायक है। आप इसका उपयोग कंसोल लॉग को पास करने और ऑब्जेक्टिव-सी फ़ंक्शन को कॉल करने के लिए कर सकते हैं।
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
स्विफ्ट 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")
}
फिर आपके जावास्क्रिप्ट कोड में, कॉलिंग कंसोल .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()