Safariと同様にスワイプで戻る、進む機能や将来性、パフォーマンスを考えてWKWebViewを導入してみました。
UIWebViewとの違いから、つまずいたポイントがあるので3つ紹介したいと思います。
環境
Swift3.0
Xcode8.1 (8B62)
つまずきポイント
1. WKWebViewではPOSTリクエストのHTTP Bodyが無視される
UIWebViewでは以下のようにPOSTのURLRequest
に対応していました。
let request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = ...
// OK
let uiWebView = UIWebView()
uiWebView.loadRequest(request)
// request.httpBodyの値が無視される
let wkWebView = WKWebView()
wkWebView.load(request)
WKWebViewではrequest.httpBody
に設定した値が無視されます。
そのため、今までBodyにパラメータを付与していた場合、リクエストの構造を変える必要があります。
解決方法としては、2点あります。
-
URLSessionDataTask
で取得したデータをWKWebViewの以下のメソッドに渡す。func loadHTMLString(_ string: String, baseURL: URL?) -> WKNavigation?
-
func load(_ data: Data, mimeType MIMEType: String, characterEncodingName: String, baseURL: URL) -> WKNavigation?
(iOS9以降)
- HTTP Headerにパラメータを含める
1の問題点は、backForwardList: WKBackForwardList
が効かなくなることです。
以下のWKWebViewのプロパティ、メソッドが正常に動作しなくなります。
var backForwardList: WKBackForwardList { get }
var canGoBack: Bool { get }
var canGoForward: Bool { get }
func goBack() -> WKNavigation?
func goForward() -> WKNavigation?
var allowsBackForwardNavigationGestures: Bool
Safariのようなスワイプで戻る、進む機能を実装したかったので、1番は諦めました。
僕のやりたかったケースでは2番のHeaderにパラメータを含めることで解決できました。
let request = URLRequest(url: url)
request.httpMethod = "POST"
request.allHTTPHeaderFields = ...
// OK
let wkWebView = WKWebView()
wkWebView.load(request)
2. WebView内のTwitter、Facebookボタンが効かない
以下のリンクを参考にしました。
WKWebViewでtarget="_blank"なリンクが開かない時の対処法 - Qiita
Why is WKWebView not opening links with target=“_blank” - stackoverflow
WKUIDelegate
の実装をするのが一番簡単そうです。
// WKUIDelegateの設定
webView.uiDelegate = self
// WKUIDelegateのメソッド
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
/*
TwitterのTweetボタン、
Facebookのいいねボタン、
target="_blank"のリンクなど、
新しいウィンドウが開く場合、これを書く必要がある。
*/
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
3. iOS9でscrollViewのdecelerationRateを変更できない
Cannot change WKWebView's scroll rate on iOS 9 beta / 9.3 - stackoverflow
上記の投稿に解決方法がありました。
webView.scrollView.delegate = self
としておいて、
extenstion WebViewController: UIScrollViewDelegate {
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
scrollView.decelerationRate = UIScrollViewDecelerationRateNormal
}
}
とすることでdecelerationRateを設定することができます。
さらに、EXC_BAD_ACCESSでクラッシュすることがあったので、ViewControllerのdeinit時に以下を書いておくと良いと思います。
deinit {
webView.scrollView.delegate = nil
}