Web Kitの Cocoa バインディングを使う


HOME > TIPS > はじめてのブラウザのつくりかた > はじめてのブラウザのつくり方 10.3

Web Kitの Cocoa バインディングを使う

Mac OS X 10.3 からは、Web Kit が標準でつくようになった!これを受けて、Interface Builder に Web Kit のサポートが追加されたんだ。これで、アクションやデリゲートの設定が Interface Builder で行えるぜ。さらにさらに、10.3 では WebView が Cocoa バインディングに対応したんだ!このおかげで、もっと多くの設定を Interface Builder でできるようになった。10.2 では、デリゲートから取り出していたページのタイトルとかも、Interface Builder で設定できちゃう。そのへんのことろを見てみよう。


1.1 Cocoa バインディング

Cocoa バインディングというのは Mac OS X 10.3 から導入されたもので、特に MVC アーキテクチャの C であるコントローラへの対応が追加された。。詳しいことは、panther-devの Cocoa バインディング関連のドキュメントを読んでくれ。ここで理解しておきたいことは、Cocoa バインディングを使うとビュー(つまりユーザインタフェース)の値を、コントローラに結びつけて、自動更新ができる、っていうことかな。この設定は Interface Builder で行える。つまり、コードを書く量ががくっ、と減ることになるんだ。ちなみに、このコントローラとビューを結びつけることをバインディングっていうんだ。

そして、10.3 からは WebView が Cocoa バインディングに対応した。ここでは、ちょっと混乱するんだけど、WebView がコントローラとして働く。WebView は、ページのタイトルやアイコンといったプロパティを提供して、ビューがそれを利用することができるんだ。

WebView が提供しているプロパティは、以下の通りだ。

  • mainFrameURL:メインフレームの URL だ。
  • isLoading:ページが読み込み中かどうかを示すんだ。
  • estimatedProgress:ページの読み込みの進行度合いを、0.0 から 1.0 で示すんだ。
  • canGoBack:前のページに戻れるかどうかを、論理値で示すんだ。
  • canGoForward:次のページに進めるかどうかを、論理値で示すんだ。
  • mainFrameTitle:メインフレームのタイトルだ。
  • mainFrameIcon:メインフレームのアイコンだ。

なんとなく、使い道が分かるでしょう?たとえば、mainFrameURL は URL テキストフィールドとバインディングしてやればよさそうだし、mainFrameTitle はウィンドウのタイトルとバインディングすればいいんだ。それだけで URL とタイトルは常に更新される。リダイレクトで URL が変更したりしても、ちゃんと追随するんだ。これは楽ちん。

1.2 実装

では、実装してみよう。今回は新規プロジェクトを立ち上げるぜ。あと分かっていると思うけど、Mac OS X 10.3 と 10.3 の開発環境、つまり Xcode が必要だ。

1. 新規プロジェクトを作る。Xcode を立ち上げて、新規プロジェクトを作ってくれ。テンプレートには Cocoa Document-Based Application を使おう。

2. プロジェクトに WebKit フレームワークを追加す る。「プロジェクト」→「フレームワークの追加」メニューを選ぼう。そして、 /System/Library/Frameworks/WebKit.framework を追加する。

3. MyDocument.nib を編集する。MyDocument.nib を開いて、Interface Builder に移動してくれ。

4. ウィンドウをレイアウトする。一気にこれだけの部品を並べよう。WebView は、GraphicsViews のパレットからドラッグしてくることができる。ボタンとウィンドウは、今回はメタル調にしてみた。あと、アイコンを表示するためのイメージビューと、読み込み状態を表すプログレスバーも貼ろう。これらは見えなくなっているので、注意してくれ。

layout-2.jpg
図1-1 ウィンドウのレイアウト

5. ビューのバインディングを設定する。前のステップで、WebView をドラッグして貼付けたでしょ?それはつまり、WebView のインスタンスを作る、っていうことを意味している。で、WebView のインスタンスを作ると、それをコントローラとしてバインディングを設定することが可能になるんだ。

では、例として URL テキストフィールドのバインディングをしてみよう。こいつは mainFrameURL とバインディングする。テキストフィールドを選択して、インスペクタパネルの Bindings パネルを開いてくれ。そうするとバインディングできる項目が出てくるので、そのなかから value バインディングを表示させよう。

バインディングの設定は、バインドする相手を設定する Bind to、コントローラのプロパティを指定する Controller Key、モデルのキーを指定する Mode Key Path の 3 つから構成される。ただ WebView の場合は、Controller Key を設定できないようになっている。これは WebView が、コントローラとモデルの両方の役割を兼ねているから、と解釈すればいいのかな。

ここでは、Bind to に WebView を選択し、Model Key Path から mainFrameURL を選択する。これでオッケーだ。

binding.jpg
図1-2 URL テキストフィールドのバインディング

同様に、残りのユーザインタフェースにもバインディングを設定しよう。以下のような感じでやってくれ。

戻るボタン:enable バインディングに canGoBack を設定。
進むボタン:enable バインディングに canGoForward を設定。
停止ボタン:enable バインディングに isLoading を設定。
再読み込みボタン:enable バインディングに isLoading を設定して、Value Transformer に NSNegateBoolean を設定。
アイコンイメージビュー:value バインディングに mainFrameIcon を設定。
プログレスバー:value バインディングに estimatedProgress を設定。
ウィンドウ:title バインディングに mainFrameTitle を設定。

これで完了。

6. アクションを設定する。ボタンとテキストフィールドから、WebView へアクションをつなぐんだ。次のように設定してくれ。

  • 戻るボタン:goBack:
  • 進むボタン:goForaward:
  • 停止ボタン:stopLoading:
  • 再読み込みボタン:reload:
  • 縮小ボタン:makeTextSmaller:
  • 拡大ボタン:makeTextLarger:
  • URL テキストフィールド:takeStringURLFrom:

ここまでできたら、保存して Xocde に戻ってくれ。

7. ビルドして実行する。これだけで動く。ソースコードは一行も書いていないよね?書いていないけれども、これだけの機能が実現できている。

・URL を指定して、Web ページを読み込む。

・リンクをクリックして、ページを移動する。

・戻る、進む、停止、再読み込みボタンなどが機能している。

・Web ページのタイトルが、ウィンドウのタイトルに設定される。

・リンクをクリックしたり、リダイレクトでページが移動すると、テキストフィールドに反映される。

・Web ページのアイコンが反映される。

・読み込みの状態を示すプログレスバーが動く。

これらのうち、最後の 4 つは Cocoa バインディングによる恩恵なんだ。

browser-8.jpg
図1-3 MyFirstBrowserPanther1 動作図


■ここまでのプロジェクト:
MyFirstBrowserPanther.zip