カテゴリー: iOS

UIWebViewからWKWebViewへの移行

はじめに

UIWebViewを使用してアプリのアップデートができる期限が2020年の12月までと正式に期限が通知されましたね。

ITMS-90809: Deprecated API Usage – App updates that use UIWebView will no longer be accepted as of December 2020. Instead, use WKWebView for improved security and reliability. Learn more (https://developer.apple.com/documentation/uikit/uiwebview).

After you’ve corrected the issues, you can upload a new binary to App Store Connect.

そこで、今回はUIWebViewからWKWebViewへの移行を行なっていきたいと思います。

ターゲットとなるUIWebViewで行なっていること

今回は以下の機能を実装しているUIWebVIewをターゲットにし、これらの機能をWKWebViewに移行していきます。

  1. URLへのアクセス
  2. ローカルHTMLの読み込み
  3. ページを戻す、進める
  4. ページの読み込み開始時や終了時に処理を行う(delegate)
  5. JavaScriptの実行
  6. Cookieの付与

URLへのアクセス

まずは基本中の基本、URLへのアクセスの方法から、UIWebViewの場合は loadRequest 関数を使用します。

func load(url: URL) {
    let request = URLRequest(url: url)
    uiWebView.loadRequest(request)
}

これをWKWebViewに置き換えるとこうなります。

func load(url: URL) {
    let request = URLRequest(url: url)
    wkWebView.load(request)
}

引数が URLRequest  なのは変わらずで、 load 関数を使用します。

ローカルHTMLの読み込み

UIWebViewでローカルHTMLを読み込む場合は loadHTMLString 関数を使用します。

uiWebView.loadHTMLString(html, baseURL: url)

WKWebViewでも変わらず loadHTMLString 関数を使用します。

_ = wkWebView.loadHTMLString(html, baseURL: url)

両者の違いとしてWKWebViewは戻り値として WKNavigation が返却されます。

ページを戻す、進める

UIWebViewでページを戻したり進めたりする場合は下記のように、履歴があるかの確認を行なってから goBack や goForward 関数を実行します。

func goBack() {
    if (self.uiWebView.canGoBack) {
        self.uiWebView.goBack()
    }
}
func goForward() {
    if (self.uiWebView.canGoForward) {
        self.uiWebView.goForward()
    }
}

この関数に関してはWKWebViewも全く同じ名前のメソッドを使用します。

func goBack() {
    if (self.wkWebView.canGoBack) {
        self.wkWebView.goBack()
    }
}
func goForward() {
    if (self.wkWebView.canGoForward) {
        self.wkWebView.goForward()
    }
}

ページの読み込み開始時や終了時に処理を行う(delegate)

ページの読み込み開始時や終了時に処理を行うには delegate を使用して処理を行います。UIWebViewは UIWebViewDelegate を使います。

extension ViewController: UIWebViewDelegate {
    // ページの読み込み開始時に呼ばれる
    func webViewDidStartLoad(_ webView: UIWebView) {
        print("Start Loading Page")
    }
    
    // ページの読み込み完了時に呼ばれる
    func webViewDidFinishLoad(_ webView: UIWebView) {
        print("Finish Loading Page")
    }
    
    // 読み込みエラー発生時に呼ばれる
    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
        print("Failed Loading Page: \(error)")
    }
}

WKWebViewの場合は、 WKNavigationDelegate を使います。

extension ViewController: WKNavigationDelegate {
    // ページの読み込み開始時に呼ばれる
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("Start Provisional Navigation")
    }
    
    // ページの内容受信開始時に呼ばれる
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        print("Did Commit")
    }
    
    // ページの読み込み完了時に呼ばれる
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("Did Finish")
    }
    
    // ページの読み込みエラー発生時に呼ばれる
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        print("Did Fail Provisional Navigation")
    }
}

WKNavigationDelegate プロトコルの方が少し細かい単位になっていて、ページの読み込み処理を開始と内容受信が分かれています。例えば、接続出来ないURLが指定されたときに、 webView(_: didStartProvisionalNavigation:) メソッドは呼ばれますが、 webView(_: didCommit:) は呼ばれないという動作になります。

JavaScriptの実行

JavaScriptの実行方法も移行が必要です、UIWebViewは stringByEvaluatingJavaScript 関数を使用しています。

let result = uiWebView.stringByEvaluatingJavaScript(from: script)

それに対し、WKWebViewでは evaluateJavaScript 関数を使用します。

wkWebView.evaluateJavaScript(script) { (result, error) in

}

UIWebViewは同期処理になっていて、JavaScriptの実行が完了してからアプリに制御が戻ります。
WKWebViewの方は非同期処理になっていて、JavaScriptの実行が完了すると、指定したブロックが実行されます。

Cookieの付与

UIWebViewでは HTTPCookieStorage を参照しているので Cookie を設定したい場合は以下のようにします。

let cookie = HTTPCookie(properties: [
    .domain: "example.com",
    .path: "/",
    .name: "MyCookieName",
    .value: "MyCookieValue",
    .secure: "TRUE",
    .expires: Date()
])!

HTTPCookieStorage.shared.setCookie(cookie)

WKWebViewの場合は以下のように設定します。

let cookie = HTTPCookie(properties: [
    .domain: "example.com",
    .path: "/",
    .name: "MyCookieName",
    .value: "MyCookieValue",
    .secure: "TRUE",
    .expires: Date()
])!

wkWebView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)

さいごに

新規でアプリを作成されている方はWKWebViewだと思いますが、UIWebViewを使用されている方も結構いるのではないかと思います。まだ12月まで余裕はありますが間際になって慌てないように余裕を持って移行していきたいですね。

おすすめ書籍

nukky

シェア
執筆者:
nukky
タグ: SwiftiOS

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

4週間 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前