UIWebViewを使用してiPhone / iPadアプリを作成する場合、コンソールは表示されません。 この優れた回答は、エラーをトラップする方法を示していますが、console.log()も使用したいと思います。
UIWebViewを使用してiPhone / iPadアプリを作成する場合、コンソールは表示されません。 この優れた回答は、エラーをトラップする方法を示していますが、console.log()も使用したいと思います。
回答:
今日、尊敬されている同僚と相談した後、彼はSafari Developer Toolkitと、これをiOSシミュレーターのUIWebViewsに接続してコンソール出力(およびデバッグ)する方法について私に警告しました。
手順:
[the name of your UIWebView file]
複雑な(私の場合はflot)Javascriptやその他のものをUIWebViewsにドロップして、自由にデバッグできるようになりました。
編集:@Joshua J McKinnonが指摘しているように、この戦略はデバイスでUIWebViewをデバッグするときにも機能します。デバイス設定でWebInspectorを有効にするだけです:[設定]-> [Safari]-> [詳細設定]-> [Web Inspector](@ Jeremy Wiebeに乾杯)
更新:WKWebViewもサポートされています
javascriptを使用してアプリのデバッグコンソールにログを記録するソリューションがあります。少し粗雑ですが、機能します。
まず、javascriptでconsole.log()関数を定義します。この関数は、ios-log:urlを使用してiframeを開き、すぐに削除します。
// 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() javascript関数をオーバーライドします。
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
あなたのwebviewswiftファイルにリンクすることを忘れないでください。
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
、それは完璧に機能します!
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);
};
この手法の利点は、ログメッセージの改行などが保持されることです。
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")
}
次に、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()