【たのしいCocoa】05_RSSリーダ

【たのしいCocoa】05_RSSリーダ
【たのしいCocoa】05_RSSリーダ

たのしいCocoaプログラミング[Leopard対応版]」を元に、要約メモしておきたいと思います。

チュートリアル:RSSリーダ

【たのしいCocoa】05_RSSリーダ
【たのしいCocoa】05_RSSリーダ

プロジェクトの作成

  • 【1】Xcode を起動する
  • 【2】プロジェクトを作成する
    「ファイル > 新規プロジェクト」メニューを選択して「Cocoa Application」テンプレートを選択。
  • 【3】ガベージコレクションの設定
    プロジェクトウィンドウのターゲットの項目を開いて、RSS Reader という名前の「ターゲット」をダブルクリック。このウィンドウで「ビルド」のタブをクリック。ビルドの設定を行う画面になるので、「構成」をすべての構成、「表示」を全ての設定にする。ここから「Objective-C Garbage Collection」という設定項目を探し、「Required」を指定する。
【たのしいCocoa】05_RSSリーダ
【たのしいCocoa】05_RSSリーダ

クラスの作成

このアプリケーションのための、AppController という名前のコントローラクラスを作る。

  • 【4】クラスを作成する
    「ファイル > 新規ファイル」メニューを選択。テンプレート一覧から「Objective-C class」を選択。
  • 【5】AppController.h を開いて、次のように編集して保存。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #import <cocoa/Cocoa.h>
    @interface AppController : NSObject {
     NSXMLDocument* document;
     
     IBOutlet NSTextField* urlTextField;
     IBOutlet NSTextField* titleTextField;
     IBOutlet NSTextField* linkTextField;
     IBOutlet NSTableView* tableView;
    }
    - (IBAction)readURL:(id)sender;
    @end

これで、コントローラとなるクラスを作成した。このクラスには5つのインスタンス変数があるが、これらのうと4つがアウトレット。また、メソッドは1つで、これはアクションになる。

ユーザインタフェースデザイン

■ 部品の配置

  • 【6】xib ファイルを開く
    ライブラリの「Cocoa > View & Cells」の下にある、「Inputs & Values」からテキストフィールド、「Buttons」からボタンを、「Data Views」からテーブルビューをそれぞれ配置する。
  • 【7】ウィンドウ上に部品を配置していく。全部で8つ。
【たのしいCocoa】05_RSSリーダ
【たのしいCocoa】05_RSSリーダ

■ テキストフィールドの設定

左上の「URL:」「Title:」「Link:」のテキストフィールドの文字揃えを右揃えにする。

  • 【8】テキストフィールドを設定する
    インスペクタパネルの Attributes タブを選択し、Alignment: で右揃えにして調整を行う。 次に、編集可能なテキストフィールドを選択する。同じく Attributes タブの「Action」と書かれているポップアップメニューから「Set On Enter Only」を選択。これで、enter キーを押したときにだけアクションが送られるようになる。

■ テーブルビューの設定

今回のアプリケーションでは、スッキリさせるために横スクロールバーを外すことにする。

  • 【9】テーブルビューの設定をする

    追加したテーブルビューをクリックすると、いま選択しているものが何のクラスであるかがインスペクタのタイトルバーに表示される。スクロールビューが選択されている状態で、インスペクタの Attributes タブに「Show Horizontal Scroller」のチェックボックスを外す。続いて、この状態でもう一回クリックすると、タイトルが「Table View」になる。このように、インスペクタのタイトルを見ながら慎重にクリックする。

    「Col. Sizing」というポップアップメニューがあるので、ここから「Uniform」を選択する。これで、テーブルビューの大きさを変更したときに、列のサイズも均等に変わることになる。

    【たのしいCocoa】05_RSSリーダ
    【たのしいCocoa】05_RSSリーダ

    次はテーブルのヘッダの部分をクリックする。タイトルが「Table Header View」となる。さらにクリックして、テーブルのヘッダのみが白く強調され、他がグレーアウトになるようにする。この状態で列の大きさが調節できる。2つの列が同じ大きさになるように調整する。

    【たのしいCocoa】05_RSSリーダ
    【たのしいCocoa】05_RSSリーダ

    列にタイトルも設定する。ヘッダをダブルクリックすることで、タイトルを設定することができる。左側には「Title」、右側には「Link」を入力する。

    続いて、列の識別子も設定する。いったんテーブルビューの外側のウィンドウをクリックして選択を解除する。再びテーブルビューをクリックして「Table View」を選択した状態にする。この状態でテーブルビューの左側の領域をクリックすると、左側だけが強調表示されて、インスペクタのタイトルが「Table Column」となる。この状態でテーブルそれぞれの列の細かい設定を行うことができる。 インスペクタの「Identifier」で、Title 列は「title」、Link 列は「link」と入力する。そして、それぞれ「Editable」のチェックを外す。

【たのしいCocoa】05_RSSリーダ
【たのしいCocoa】05_RSSリーダ

■ 自動リサイズの設定

自動リサイズは、部品ごとにインスペクタの Size タブで設定する。下半分にある「Autosizing」で設定を行う。

  • 【10】自動リサイズの設定をする
    まず URL テキストフィールドの設定を行う。「URL:」と書いてあるテキストフィールドを選択して、インスペクタの Size タブを表示する。このテキストフィールドは左上に固定する。
    同様に、全ての部品を設定していく。「Title:」「Link:」は左上固定。編集可能なテキストフィールド、「title」「link」のテキストフィールドは上に固定で横方向にはリサイズ。「Read」ボタンは右上固定。 テーブルビューはスクロールビューの中に入れられているので、リサイズの変更は外側のスクロールビューに対して行う。
【たのしいCocoa】05_RSSリーダ
【たのしいCocoa】05_RSSリーダ
  • 【11】リサイズのテストをする
    「File > Simulate Interface」メニューを選択すると、部品の動きをテストする。このモードから抜けるには「Cocoa Simulator > Quit Cocoa Simulator」メニューを選択する。

■ ウィンドウの設定

最後に、ウィンドウの設定をする。

  • 【12】ウィンドウのタイトルを設定する
    ウィンドウを選択して、インスペクタの Attributes タブを表示する。「Title」のテキストフィールドに「RSS Reader」と入力する。

これでユーザインタフェースのデザインは完了。

クラスのインスタンス化

  • 【13】クラスをインスタンス化する
    ライブラリの「Cocoa > Objects & Controllers > Controllers」にある Object を xib ウィンドウにドラッグして追加する。そのオブジェクトを追加したままインスペクタを追加し、Identity タブで「AppController」クラスを選択する。

アウトレットとアクションの接続

■ AppController のアウトレットとアクション

  • 【14】アウトレットとアクションを接続する まずテキストフィールドのアウトレットを接続する。「urlTextfield」「titleTextField」「linkTextField」を、xib ウィンドウの AppController からコントロールキーを押しながらドラッグして、それぞれ接続する。テーブルビューも接続するが、注意して「NSTableView」というクラスを接続する。 アクションも接続する。「Read」ボタンからコントロールキーを押しながら AppController にドラッグして「readURL:」アクションに接続する。入力可能なテキストフィールドからも「readURL:」アクションに接続する。

■ テーブルビューのアウトレットの接続

  • 【15】テーブルビューのアウトレットを接続する アプリケーションのメインウィンドウでテーブルビューを何度かクリックして、スクロールビューではなくテーブルビューを選択した状態にする。その状態でコントロールキーを押しながら AppController にドロップする。そこで「dataSource」を選択する。

AppController クラスの実装

  • 【16】AppController.m を編集する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#import "AppController.h"
 
@implementation AppController
 
- (IBAction)readURL:(id)sender
{
 NSURL*  url;
 url = [NSURL URLWithString:[urlTextField stringValue]];
 
 // XMLドキュメントを作成します
 document = [[NSXMLDocument alloc] initWithContentsOfURL:url options:0 error:NULL];
 if (!document) {
  return;
 }
 
 // '/rss/channle/title'のノードを取得します
 NSArray*    nodes;
 nodes = [document nodesForXPath:@"/rss/channel/title" error:NULL];
 if ([nodes count] == 0) {
  // '/rdf:RDF/channel/title'のノードを取得します
  nodes = [document nodesForXPath:@"/rdf:RDF/channel/title" error:NULL];
 }
 if ([nodes count] == 0) {
  // '/feed/title'のノードを取得します
  nodes = [document nodesForXPath:@"/feed/title" error:NULL];
 }
 
 if ([nodes count] == 1) {
  NSXMLNode* titleNode;
  titleNode = [nodes objectAtIndex:0];
 
  // テキストフィールドにタイトルを設定します
  NSString*   title;
  title = [titleNode stringValue];
  [titleTextField setStringValue:title];
 }
 
 // '/rss/channle/link'のノードを取得します
 nodes = [document nodesForXPath:@"/rss/channel/link" error:NULL];
 if ([nodes count] == 0) {
  // '/rdf:RDF/channel/link'のノードを取得します
  nodes = [document nodesForXPath:@"/rdf:RDF/channel/link" error:NULL];
 }
 if ([nodes count] == 0) {
  // '/feed/link'のノードを取得します
  nodes = [document nodesForXPath:@"/feed/link" error:NULL];
 }
 
 if ([nodes count] == 1) {
  NSXMLNode* linkNode;
  linkNode = [nodes objectAtIndex:0];
 
  // テキストフィールドにリンクを設定します
  NSString*   link;
  link = [linkNode stringValue];
  [linkTextField setStringValue:link];
 }
 
 // テーブルビューにデータを読み込みます
 [tableView reloadData];
}
// NSTableViewデータソース
- (int)numberOfRowsInTableView:(NSTableView*)tableView
{
 if (!document) {
  return 0;
 }
 
 // '/rss/channel/item/'のノードを取得します
 NSArray*    nodes;
 nodes = [document nodesForXPath:@"/rss/channel/item" error:NULL];
 if ([nodes count] == 0) {
  // '/rdf:RDF/item'のノードを取得します
  nodes = [document nodesForXPath:@"/rdf:RDF/item" error:NULL];
 }
 if ([nodes count] == 0) {
  // '/feed/entry'のノードを取得します
  nodes = [document nodesForXPath:@"/feed/entry" error:NULL];
 }
 
 // ノードの数を返します
 return [nodes count];
}
 
// NSTableViewデータソース
- (id)tableView:(NSTableView*)tableView objectValueForTableColumn:(NSTableColumn*)tableColumn row:(int)row
{
 if (!document) {
  return nil;
 }
 
 // テーブルカラムの識別子を取得します
 id  identifier;
 identifier = [tableColumn identifier];
 
 // '/rss/channel/item/'のノードを取得します
 NSArray*    nodes;
 nodes = [document nodesForXPath:@"/rss/channel/item" error:NULL];
 if ([nodes count] == 0) {
  // '/rdf:RDF/item'のノードを取得します
  nodes = [document nodesForXPath:@"/rdf:RDF/item" error:NULL];
 }
 if ([nodes count] == 0) {
  // '/feed/entry'のノードを取得します
  nodes = [document nodesForXPath:@"/feed/entry" error:NULL];
 }
 
 // 指定された行の、ノードを取得します
 NSXMLNode*  node;
 node = [nodes objectAtIndex:row];
 
 if ([identifier isEqual:@"title"]) {
  // 'title'の文字列を取得します
  nodes = [node nodesForXPath:@"title" error:NULL];
  if ([nodes count] == 1) {
  node = [nodes objectAtIndex:0];
  return [node stringValue];
  }
 }
 
 if ([identifier isEqual:@"link"]) {
  // 'link'の文字列を取得します
  nodes = [node nodesForXPath:@"link" error:NULL];
  if ([nodes count] == 1) {
   node = [nodes objectAtIndex:0];
   return [node stringValue];
  }
 }
 
 return nil;
}
@end 1

ビルドと実行

  • 【17】ビルドと実行
    「ビルド > ビルドと実行」メニューを選択。

こちらの関連記事もあわせてどうぞ!

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">