Edited at

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

More than 5 years have passed since last update.

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

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

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

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

https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/WebKit/ObjC_classic/index.html

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


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 でついに使えるようになる!とのことです。

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