53
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOSのWKWebViewの3つのつまずきポイントと解決方法

Last updated at Posted at 2016-11-12

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点あります。

  1. 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
}
53
44
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?