バインディングを使った Cocoa アプリケーションチュートリアル抄訳
以下は Xcode 3.2 のデベロッパドキュメント 「Mac OS X 10.6 Core Library」 もしくは 「Mac OS X Leopard Core Library」 の 「Cocoa Application Tutorial Using Bindings」 の抄訳。 オリジナルでは Xcode および Interface Builder の画面と操作が、 バージョン 3.2 に対応した説明ではないので、 画面と操作を中心に読み替えた点を備忘として記すことにした。
概要
このチュートリアルでは Cocoa バインディングを使って、 おなじみの Currency Converter (通貨換算機) アプリケーションを作成する手順を紹介します。 (訳注: 「おなじみの」 と言っているのは、 すでに 「Cocoa Application Tutolial」 などでサンプルアプリケーションとして使用しているから。 したがってこのチュートリアルではすでに解説したと思われる細かい話は出てこないので注意。)
プロジェクトとインタフェースを作る
新しいプロジェクトを作る
- /Developer/Applications にある Xcode アプリケーションを起動します。
- 「ファイル>新規プロジェクト」 を選びます。
- Cocoa Application を選び、 「選択...」 ボタンをクリックします。
- プロジェクト名を 「CurrencyConverter」 と入力し、 プロジェクトの保存先のフォルダを指定して保存します。
- プロジェクトができたら、 プロジェクトの 「Resourecs」 フォルダの中の MainMenu.xib アイコンをダブルクリックして Interface Builder で開きます。
Cocoa アプリケーションプロジェクトを選ぶ
ユーザインタフェースを作る
このチュートリアルにおける Currency Coverter のユーザインタフェースの最終形態を下図に示します。 「Exchange Rate (換算率)」 と 「Dollars to Convert (換算するドル)」 フィールドの値に基づいて、 「Amount in Other Currency (他の通貨の価)」 フィールドに計算した値を表示します。
- アプリケーションウィンドウのタイトルを 「Currency Coverter」 にします。
- 3つのラベル (Label) と数値フォーマッタ付きテキストフィールド (TextField with Number Formatter) を、 Library パネルからドラッグアンドドロップします。
- 3つのラベルを 「Exchange Rate:」、 「Dollars to Convert:」、 「Amount in Other Currency:」 に変更します。
- テキストフィールドと対応するラベルの位置がマッチするように調整します。
- テキストフィールドの数値フォーマッタを設定します (数値フォーマッタを選択してから Inspector パネルの Attributes タブをクリックして設定できます。)
モデルの作成
モデルを作成する
次に、 アプリケーションのモデルオブジェクトを実装します。 モデルオブジェクトは、 「Exchange Rate」 と 「Dollars To Convert」 のテキストフィールドに入力された値に基づいて、 他の通貨の価 (Amount in Other Currency) を計算します。
モデルオブジェクトは NSObject のサブクラスとして作成します。 以下のように Interface Builder を使います。
- Library パレットで 「Classes」 タブをクリックします。
- NSObject を選択して Library パレットの左下のギアアイコンから 「New Subclass...」 を選びます。 または NSObject をコントロール + クリックして、 コンテキストメニューから選ぶことも出来ます。
- 新しいクラスの名前は 「Converter」 にします。 「Generate source files」 をチェックしておきます。 OK ボタンをクリックします。
- 生成する
Converter.m
を保存する場所を指定します。 Save ボタンをクリックします。 - 生成した
Converter.m
、Converter.h
をCurrencyConverter
プロジェクトに追加します。 Add ボタンをクリックします。
後は、 このクラスが Cocoa バインディング出来るようにするために、 必要なインスタンス変数とアクセサメソッドを Converter クラスに追加します。
Converter.h に以下の宣言を追加します。
@interface Converter : NSObject { double dollarsToConvert; double exchangeRate; } @property(readwrite) double dollarsToConvert, exchangeRate; -(double)amountInOtherCurrency; @end
Converter.m にアクセサメソッドを追加します。
@synthesize dollarsToConvert, exchangeRate; -(double)amountInOtherCurrency { return self.dollarsToConvert * self.exchangeRate; }
上のコードを見るとわかるように、
amountInOtherCurrency
の値は、
単純に dollarsToConvert
または exchangeRate
の値を設定しても、
再計算されません。
そこで Cocoa バインディングでは、
依存するキーを更新するために変更通知を送る仕組みを提供しています。
では amountInOtherCurrency
キーの値が更新されるように、
dollarsToConvert
と exchangeRate
との間に依存関係を設定しましょう。
この依存関係はモデルクラスの +keyPathsForValuesAffectingValueForKey:
で設定します。
Converter の
+keyPathsForValuesAffectingValueForKey:
メソッドを実装します。+(NSSet*)keyPathsForValuesAffectingValueForKey:(NSString*)key { if ([key isEqualToString:@"amountInOtherCurrency"]) { return [NSSet setWithObjects:@"dollarsToConvert", @"exchangeRate", nil]; } return nil; }
最後に、 モデルクラス Converter のインスタンスを xib ファイルに追加します。
- Interface Builder の Library パレットで 「Classes」 タブをクリックします。
- Converter クラスをドラッグして MainMenu.xib ウィンドウにドロップします。
オブジェクトコントローラの作成
コントローラを追加する
次にコントローラオブジェクトを xib ファイルに追加します。 コントローラオブジェクトには、 単一オブジェクトを管理する NSObjectController、 オブジェクトの配列を管理する NSArrayController、 ユーザデフォルトデータベースとやり取りをする NSUserDefaultsController、 などがあります。
Currency Converter アプリケーションは単一のモデルオブジェクトを持っていますので、 NSObjectController を使います。
- Library パレットの 「Objects」 タブをクリックします。
- Object Controller オブジェクトをドラッグして MainMenu.xib ウィンドウにドロップします。
モデル-コントローラの関係を確立する
インスタンス化したコントローラオブジェクトと、 それがコントロールするモデルオブジェクトを関連づけます。
- MainMenu.xib ウィンドウの中で、 Object Controller コントローラオブジェクトを選択します。
- Object Controller コントローラオブジェクトからコントロールキーを押しながらドラッグして、 Converter モデルオブジェクトに接続します。
- content アウトレットを選択します。
次に、 モデルオブジェクトの中のキーを、 コントローラが識別できるようにします。
- MainMenu.xib ウィンドウの中の Object Controller オブジェクトを選択します。
- Inspector パネルの 「Attributes」 タブを選択します。
- Key リスト左下の「+」(追加)ボタンをクリックして、3つのキー 「dollarsToConvert」、 「exchangeRate」、 「amountInOtherCurrency」 を追加します。
Object Controller インスタンスの Attributes ペイン
ビューとコントローラのバインディング
ビューとコントローラをバインドする
次に、 ビューのユーザインタフェース要素とコントローラをバインドします。
テキストフィールドのバインディング
- Currency Converter ウィンドウの 「換算率」 ラベルの横のテキストフィールドを選択します。
- Inspector パネルの 「Bindings」 タブを選択します。
- 「Value」 グループの 「value」 バインディングの左にある三角をクリックして開きます。
- 「Bind to」 メニューから 「Object Controller」 コントローラを選びます。
- 「Controller Key」 メニューから 「selection」 キーを選びます。
- 「Model Key Path」 メニューから 「exchangeRate」 キーを選びます。
- 以下、 「換算するドル」 ラベルの隣のテキストフィールドには 「dollarsToConvert」 モデルキーを、 「他の通貨の値」 ラベルの隣のテキストフィールドには 「amountInOtherCurrency」 モデルキーをバインドします。
アプリケーションを実行する
ビルドと実行
アプリケーションをビルドして実行すると、 完全に機能する Currency Converter (通貨換算機) が完成するでしょう。
以前の Currency Converter アプリケーションとは違って、 アプリケーションのモデルクラスに IBOutlet を追加したり、 ユーザが入力した値を手動で取得したり、 値を設定するためにユーザインタフェースのテキストフィールドに対して setStringValue を呼び出したりする必要がないことがわかるでしょう。 これらのたぐいのグルーコードはすべて、 Cocoa バインディングによって自動的に処理されます。
訳注: 以上、 紹介された Currency Converter アプリケーションの作り方を簡単にまとめておく。
- Xcode でプロジェクトを作る。
- IB でビューを作る。
- IB でモデルを作る。
- Xcode でモデルに変数・アクセサメソッドを追加する。
- Xcode で各変数・アクセサメソッドどうしの依存関係を定義する。
- IB でコントローラを作る。
- IB でコントローラとモデルをバインドする。
- IB でコントローラにキーを追加する。
- IB でビューのインタフェース要素にコントローラをバインドする。
こう見てみると、 ユーザインタフェース (ビュー) に関する部分を、 ほとんど IB だけで作っていることがわかる。