WKWebViewについてわかったこと。iOS 8.1.0の時点での情報です。
StackOverflowやDeveloperForumsからの情報と、私がOhajiki Web Browserを開発する過程で得た知識を短めにまとめてみました。
これ以外にもまだまだ細かい部分があるかと思いますが、より良い方法や補足などがありましたらコメント欄で是非とも教えていただければ幸いです。
iOS 9での変更点はこちら: iOS 9 WKWebView 主な変更点をざっくり
tmpフォルダ以外は file:/// を使ってアクセスできない
iOS8.0.2からtmpディレクトリ以下のファイルに fileプロトコルでアクセスすることが可能になりましたが、それ以外のディレクトリからのアクセスは無効となっています。WKWebViewが普及しない一番の要因はこれではないでしょうか。
こちらで試すことが出来ます GitHub shazron / WKWebViewFIleUrlTest
Note: iOS9.0.0(beta)でLibrary/Documents等のフォルダのファイルにアクセス可能になっています。App Bundleは不可。
- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL NS_AVAILABLE(10_11, 9_0);
Storyboard, Interface Builderで使えない
コード側で初期化・表示しNSLayoutConstraint
を設定する必要があります。
target="_blank"のaタグが無反応
そのままではリンクを押しても無反応になってしまいます。
同一のWKWebViewで開くか、新しいWKWebViewを用意する設定をしなければなりません。
WKWebViewでtarget="_blank"なリンクが開かない時の対処法
他アプリへのURLスキームやApp Storeへのリンクは自分で振り分ける必要がある
UIWebViewでは自動でURLスキームやApp Storeのリンクを開いてくれましたが、これもコードを書いて処理する必要があります。
一例: http://qiita.com/ShingoFukuyama/items/b3a1441025a36ab7659c
JavaScriptの alert, confirm, promptを表示させるためにはWKUIDelegateを使う必要がある
alert, confirm, promptはそれぞれ以下WKUIDelegateのメソッドで処理します。
webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:
webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:
webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:
WKWebViewでJavaScript(Alert,Confirm,Prompt)の処理
Basic, Digestなどの認証の入力画面表示も自分で実装する必要がある
WKNavigationDelegateの以下のメソッドを使います。
webView:didReceiveAuthenticationChallenge:completionHandler:
WKWebViewでBasic認証がかかったページへアクセスする方法 via @qmihara
Cookieを複数のWKWebViewでシェアするにはWKProcessPoolを使う
各WKWebViewの初期化時に共通のWKProcessPoolを指定する必要があります。
例:
self.processPool = [[WKProcessPool alloc] init];
WKWebViewConfiguration *configuration1 = [[WKWebViewConfiguration alloc] init];
configuration1.processPool = self.processPool;
WKWebView *webView1 = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration1];
...
WKWebViewConfiguration *configuration2 = [[WKWebViewConfiguration alloc] init];
configuration2.processPool = self.processPool;
WKWebView *webView2 = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration2];
...
NSCachedURLResponseが使えない
UIWebViewではNSURLCacheとNSCachedURLResponseを使って広告を読み込む前に除外したり、オフラインで読むということが可能でしたがWKWebViewではこの方法は使えません。
Cookie、Cache、Credential、その他Webデータなどを消したい
普通には消せないようです。試行錯誤の結果、以下の方法なら消すことができました。
- NSURLCache, NSHTTPCookieを使ってUIWebViewのときと同じようにCookie, Cacheを削除する。もしWKProcessPoolを指定している場合はWKProcessPoolも再度初期化。
- Libraryディレクトリ下のCookies, Caches, WebKitサブディレクトリを削除。
- すべてのWKWebViewを削除。
リンク長押しで出てくるメニューを無効化できない
CSS: -webkit-touch-callout: none;
、またはJavaScript: document.documentElement.style.webkitTouchCallout='none';
で無効化できるはずですが、効きません。
Note: iOS8.2から修正されています。
その他
- キャプチャがうまくいかないときがある -> 代わりに_webView.scrollViewをキャプチャ
- Xcode6.1時点でWKWebViewに対する正しいメモリ使用量が表示されない
- WKWebViewでwindow.webkit.messageHandlersが効かないサイトへの対処法
- たまにCookieがうまく保存されない: NSHTTPCookieとWKWebViewは定期的にCookieを同期している?
欲しい機能
- WKWebViewごとのページ履歴の復元: WKBackForwardListがreadonly