[iOS 8] WKWebView で Web ページのタイトルやURLを表示する 〜 Objective-C 編

前回

前回の記事 では、WKWebView で ロード中のプログレス(進捗状況)を表示する方法について解説しました。今回は表示した Web ページのタイトルとURLの取得方法について解説します。

サンプルプロジェクトを起動してみる

hirai-yuki/WebBrowserSample からサンプルプロジェクトをダウンロードして、Xcode 6 で開き、実行してみましょう(pod installを忘れずに!)。

すると、以下のように Web ページの読み込むと、ナビゲーションバーにタイトルが表示されていますね。

ios-8-wkwebview-title-url-1

ソースコードを見る

サンプルプロジェクトで プログレス表示に関する記述は以下の3箇所です。

CLMWebBrowserViewController.m WKWebView クラスの URL プロパティの変更を監視(KVO)
- (void)viewDidLoad
{
    [super viewDidLoad];

    // WKWebView インスタンスのプロパティの変更を監視する
    [self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
    [self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil];
    [self.webView addObserver:self forKeyPath:@"loading" options:NSKeyValueObservingOptionNew context:nil];
    [self.webView addObserver:self forKeyPath:@"canGoBack" options:NSKeyValueObservingOptionNew context:nil];
    [self.webView addObserver:self forKeyPath:@"canGoForward" options:NSKeyValueObservingOptionNew context:nil];

    // 初回画面表示時にIntialURLで指定した Web ページを読み込む
    NSURL *url = [NSURL URLWithString:InitialURL];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
}

- (void)dealloc
{
    // WKWebView インスタンスのプロパティの変更を監視を解除する
    [self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
    [self.webView removeObserver:self forKeyPath:@"title"];
    [self.webView removeObserver:self forKeyPath:@"loading"];
    [self.webView removeObserver:self forKeyPath:@"canGoBack"];
    [self.webView removeObserver:self forKeyPath:@"canGoForward"];
}
CLMWebBrowserViewController.m プログレスの表示を更新しているところ
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if ([keyPath isEqualToString:@"estimatedProgress"]) {
        // estimatedProgressが変更されたら、プログレスバーを更新する
        [self.navigationController setSGProgressPercentage:self.webView.estimatedProgress * 100.0f];
    } else if ([keyPath isEqualToString:@"title"]) {
        // titleが変更されたら、ナビゲーションバーのタイトルを設定する
        self.title = self.webView.title;
    } else if ([keyPath isEqualToString:@"loading"]) {
        // loadingが変更されたら、ステータスバーのインジケーターの表示・非表示を切り替える
        [UIApplication sharedApplication].networkActivityIndicatorVisible = self.webView.loading;
        
        // リロードボタンと読み込み停止ボタンの有効・無効を切り替える
        self.reloadButton.enabled = !self.webView.loading;
        self.stopButton.enabled = self.webView.loading;
    } else if ([keyPath isEqualToString:@"canGoBack"]) {
        // canGoBackが変更されたら、「<」ボタンの有効・無効を切り替える
        self.backButton.enabled = self.webView.canGoBack;
    } else if ([keyPath isEqualToString:@"canGoForward"]) {
        // canGoForwardが変更されたら、「>」ボタンの有効・無効を切り替える
        self.forwardButton.enabled = self.webView.canGoForward;
    }
}

サンプルプロジェクトで行なっていることを簡単に説明すると、「WKWebView クラスの title プロパティの変更を監視して、変更があればビューコントローラのタイトルを変更する」ということをやっています。

loading プロパティや、estimatedProgress プロパティと同じですね。

title

実は iOS 7 までは、ロードした Web ページのタイトルを取得するには、以下のようにする必要がありました。

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

UIWebView では、Objective-C から JavaScript を実行させるために - stringByEvaluatingJavaScriptFromString: メソッドがあります。iOS 7 までではこれを利用して、ロードした Web ページのタイトルを JavaScript(document.title)から取得しなければなりません。

iOS 8からは、WKWebView クラスの title プロパティより ロードしたWeb ページのタイトルが取得できるようになりました。このプロパティは UIWebView にはなく、WKWebView 独自のプロパティです。

estimatedProgress プロパティは、loading プロパティや、estimatedProgress プロパティ同様、KVOに準拠しているので、サンプルプロジェクトのように実装できます。

URL も取得できるよ

WKWebView クラスでは、Web ページのタイトルだけでなく URL も取得できます。

ちなみに、URL に関しても iOS 7 までは、以下のようにする必要がありました。

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

まとめ

iOS 7 までは、Web ページのタイトルや URL を取得するタイミングとして、よく UIWebViewDelegate の - webViewDidFinishLoad: メソッドを利用していました。これは、UIWebView で Web ページの読み込みが完了した際に実行されるデリゲートメソッドですが、WKWebView でも似たようなメソッドが、WKNavigationDelegate の - webView:didFinishNavigation: メソッドとして定義されています。

このデリゲートメソッドは title プロパティや URL プロパティに値がセットされた状態で実行されるので、ここでもこれらの値を取得することができます。

次回は、閲覧履歴について解説したいと思います。