koogawa blog

iOS、Android、foursquareに関する話題

iOS 8から追加されたWebKit Frameworkを使ってみる

Qiita でも公開しています。


※本記事は、一般に公開されている情報を元に作成しています。

iOS 8から新たに WebKit Framework が追加されました。

これにより、Webページのロードプログレスがついに取得できるようになったり、JavaScriptエラーを受け取れるようになりました。

クラスリファレンス等は一般にも公開されており、開発者以外も読むことができます。

Apple Developer Documentation

以下、私が気になった項目をまとめていきたいと思います。

UIWebViewとの関係

従来の UIWebView と WebKit Framework は別物のようです。(勝手にUIWebViewの機能強化版だと思い込んでいた)

新たに WKWebView というクラスが用意されていました。

初期化

WebKit Framework をインポート。

@import WebKit;

WKWebView インスタンスの生成。configuration については後述。

self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds
                                  configuration:configuration];

プロパティ

configuration

WebViewの設定。WKWebViewConfiguration を指定できます。

WKWebViewConfiguration クラスには preference というプロパティがあり、

  • WebViewの最小フォントサイズ
  • JavaScriptが新ウィンドウを自動的に開くのを許可するか
  • JavaScriptの実行を許可するか

などを設定できるようです。詳しくは次のクラスリファレンスを参照してください。

navigationDelegate

WebViewのナビゲーションに関するデリゲートです。詳しくは後述します。

title

現在表示しているページのタイトルが NSString で取得できるようになりました。今後は

NSString* title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];

のような処理を書かなくても良いわけですな!

ちなみに、URL プロパティで表示中の url も取得できます。

estimatedProgress

ついにページのロードプログレスがiOS標準で取得できるようになりました!このプロパティは double 型で、0.0 から 1.0 の値が入ります。ページの読み込みが完了すると 1.0 になり、新たなページの読み込みが始まると再び 0.0 にリセットされるようです。

allowsBackForwardNavigationGestures

iOS 7 から Safari に追加された「フリックで前ページに戻る・進む」がついに WebView でも使えるようになりました!このプロパティを YES にすることで機能が有効になります。デフォルトは NO のようです。

backForwardList

Webページの閲覧履歴が WebView でも扱えるようになりました。今までに閲覧してきたページのリストが WKBackForwardList クラスで取得できます。

このクラスは次のプロパティから構成されます。(例:A -> B -> C の3つのページを閲覧したあと、「戻る」で B のページに戻った場合)

  • currentItem - 現在表示しているページ(B)
  • backItem - 「戻る」で表示されるページ(A)
  • forwardItem - 「進む」で表示されるページ(C)
  • backList - 「戻る」で表示できるページのリスト(NSArray
  • forwardList - 「進む」で表示できるページのリスト(NSArray

各ページの情報は WKBackForwardListItem クラスで管理されており、タイトルとURLが取得できます。

メソッド

- reloadFromOrigin

通常の reload メソッドとは別にこのメソッドが用意されていました。ドキュメントには

Reloads the current page, performing end-to-end revalidation using cache-validating conditionals if possible.

のように書かれていました。(キャッシュを使わないリロードのこと?)

デリゲート

UIWebView と同じように、様々なデリゲートが用意されています。

例えば、あるWebページを表示しようとすると、次の順番でデリゲートが呼ばれます。

- (void)webView:(WKWebView *)webView
 didStartProvisionalNavigation:(WKNavigation *)navigation

ページの読み込み準備開始。この時点での estimatedProgress0.1 でした。

- (void)webView:(WKWebView *)webView
 didCommitNavigation:(WKNavigation *)navigation

ページが見つかり、読み込み開始。この時点での estimatedProgress0.3 以上の値が入っていました。(ちなみにページが見つからない場合、このデリゲートは呼ばれませんでした)

- (void)webView:(WKWebView *)webView
didFinishNavigation:(WKNavigation *)navigation

ページの読み込み完了。この時点での estimatedProgress1.0 でした。

- (void)webView:(WKWebView *)webView
 didFailProvisionalNavigation:(WKNavigation *)navigation
      withError:(NSError *)error

ページの読み込み失敗。この時点での estimatedProgress0.1 だったり 1.0 だったり色々。

- (void)webView:(WKWebView *)webView
didFailNavigation:(WKNavigation *)navigation
      withError:(NSError *)error

調査中。ページは見つかったけど表示できない場合?

- (void)webView:(WKWebView *)webView
didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation

表示中にリダイレクトが入ると呼ばれるようです。

パフォーマンスとか

9to5mac の情報によると、これまで Safari だけが使うことができた高速な JavaScript エンジン(Nitro)を、iOS 8 から追加された WebKit Framework でついに使えるようになる!とのことです。

今後は、サードパーティ製ブラウザや、アプリ内ブラウザの速度向上が期待できそうですね!