はてなブックマークに追加

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
はてなブックマークに追加

サーバ移行のお知らせ

このたび、blogのリニューアルに伴って
サーバをFC2からロリポップへと移行することになりました。

リニューアルサイトはこちらになります。
iPhoneアプリと、そのプログラム

よろしくお願い致します。






スポンサーサイト
はてなブックマークに追加

UIScrollViewの使い方 その5




サイトを移行しました。
iPhoneアプリと、そのプログラム



さて前回(UIScrollViewの使い方 その4)は、
タッチイベントは取得出来るようになったけれども、
スクロールができなくなってしまった、という問題が発生したのでした。

そこで、
・2本指でスワイプしたときには、スクロール動作。
・2本指でピンチイン・アウトしたときには、拡大縮小動作。
・1本指で画面をタッチした場合には座標取得
となるような、プログラムを作ってみましょう。

この方法を用いれば、指が2本の時は画面の拡大縮小移動を行ない、
指が1本であれば線を引くといったような動作が可能になるため、
多くのドローソフトではこのジェスチャが使われているようです。


この機能を実現するためには、
UIScrollViewを継承してオリジナルのScrollViewクラスを作成し、
touchesBegan:withEventメソッドなどをオーバライトする必要があります。

UIScrollView8.jpg

上図で説明すると(何度も、同じ図を使いまわしていますが ^^; )
2本指でタッチされた場合には、通常通りScrollViewの動作を行い、
1本指でタッチされた場合には、スクローズせずに、下のViewにタッチイベントを投げるような、
独自ScrollViewクラスを作成します。今回はMyScrollViewという名前でクラスを作成しました。

MyScrollView.h
@interface MyScrollView : UIScrollView {
}
@end


MyScrollView.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if( [touches count] == 1 ){
self.scrollEnabled = NO;
} else {
self.scrollEnabled = YES;
}

if (!self.dragging) {
[self.nextResponder touchesBegan: touches withEvent:event];
}
[super touchesBegan: touches withEvent: event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!self.dragging) {
[self.nextResponder touchesMoved: touches withEvent:event];
}
[super touchesMoved: touches withEvent: event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!self.dragging) {
[self.nextResponder touchesEnded: touches withEvent:event];
}
[super touchesEnded: touches withEvent: event];

}


ポイントはtouchesBegan:withEventメソッドの最初の5行です。
タップされた指の数によって、スクロールをするかしないかを決定しています。
残りの部分は、レスポンダチェーンの先にあるインスタンスに処理を投げるプログラムです。


ここまでで、タッチされた指の本数によって、
スクロールとタッチ動作を分離するScrollViewクラスが作成できました。
あとは、ViewControllerクラスでこのScrollViewクラスのインスタンスを作成&登録するだけです。

scrollViewController.h
@interface scrollViewController : UIViewController
{
MyScrollView *scrollView;
UIImageView *imageView;
}


scrollViewController.m
- (void)viewDidLoad {
[super viewDidLoad];

scrollView = [[MyScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[self.view addSubview:scrollView];
[scrollView release];

imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"test.jpg"]];
scrollView.contentSize = imageView.frame.size;
[scrollView addSubview:imageView];
[imageView release];

scrollView.contentSize = imageView.frame.size;
scrollView.delegate = self;
scrollView.minimumZoomScale = 0.5;
scrollView.maximumZoomScale = 4.0;
scrollView.delaysContentTouches = NO;
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)_scrollView
{
return imageView;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}


viewDidLoadメソッドの3行目から5行目で、
作成したScrollViewクラスのインスタンスを作成し、
Viewに登録しています。
この部分は、これまでIB側で部品を画面上に配置することで行なってきたことを
Xcodeで記述しているだけです。
scrollView.userInteractionEnabled=NO;の行を消した以外は、前回とほとんど同じですね~。
後は、touchesBegan:withEventメソッドなどの中に座標を計算するプログラムを書けば完成です。


プロジェクトファイルをココに置いておきます。
参考にしてみてください。
scroll4.zip

はてなブックマークに追加

iPhoneアプリ・電卓をつくる その3




サイトを移行しました。
iPhoneアプリと、そのプログラム


さて、前回
iPhoneアプリ・電卓をつくる その2
はiPhoneプログラミングの概要だけで終わってしまったので、
今日は、実際にプログラムを書いていきます。

Calc1ViewController.h
@interface Calc1ViewController : UIViewController {
IBOutlet UILabel *label;
int count;
}
-(IBAction) plusButtonPressed;
@end


もういちど、前回のプログラムイメージを再掲します。
ここで、今回のカウンタプログラムの場合、
この図の各部分が何に相当するのかを考えてみましょう。

calc5.jpg

まず、ユーザイベントは「+ボタンの押下」で、
画面更新は、「UILabelの更新」ですね。

そこで、ボタンが押されたときに呼ばれる自作関数plusButtonPressedには
IBActionを付けて定義しています。また、画面更新の対象であるUILabelには
IBOutletをつけて宣言しています。これは、前回の説明通りです。
あとはボタンが押下されたときに呼ばれる関数の中身を実装するだけです。

Calc1ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
count = 0;
}

-(IBAction) plusButtonPressed
{
count++;
label.text = [NSString stringWithFormat:@"%d", count];
}


まずは、何回「+ボタン」が押されたのかを保持する変数
countをヘッダファイルに宣言しておき、viewDidLoad関数の中で初期化します。
基本的にはviewDidLoad関数のなかで変数を初期化するようにしておけば大丈夫です。

最後に、ボタンが押下されたときに呼ばれる関数plusButtonPressedの中身を見ていきます。
まず、countをインクリメントしておき、その値をLabelとして表示するため
stringWithFormatという関数を用いて、int型をNSString型に変換しています。
その結果をlabel.textに代入することで、画面上の表示が更新されます。


さて、もう一度インタフェースビルダーに戻って、
イベントと自作関数、画面更新を関係付けます。
具体的には、上図の青矢印と赤矢印を引く感じですかね~。

まずは、IB(Interface Builder)のCacl1ViewController.xibウインドウから
File's Ownerを選択した状態にします。
calc7.jpg

この状態で、インスペクタをみると
このような状態になっているかと思います。

calc10.jpg

この状態でlabelの右側にある○からViewウインドウのUILabelに向けてドラッグします。
同様に、plusButtonPressedの右側の○から+ボタンに向けてドラッグし、
touch up insideを選択します。

うまくいけば、このようになるかと思います。

calc8.jpg

あとはXcodeに戻ってコンパイル&実行すれば
うまくカウンタが動作するはずです。

ここまでのプロジェクトファイルをここに置いておきます。
Calc1.zip


さてさて、宿題です。
(ゼミ資料を兼ねてるもので・・・笑)
これまでのカウンタプログラムにクリアボタンをつけて、
クリアボタンが押されたときにはカウントを0に戻すようにしてみてください。

こんな感じです。

calc9.jpg

クリアボタンをつけたバージョンのプロジェクトファイルをここに置いておきます。
Calc2.zip



はてなブックマークに追加

iPhoneアプリ・電卓をつくる その2




サイトを移行しました。
iPhoneアプリと、そのプログラム



さて、前回はインタフェースビルダーを用いて、電卓のカウンタのインタフェースを設計しました。
今回は、プログラムをかいていきましょう。

iPhoneプログラミングは、C言語の教科書に載っているような「main関数から始まって・・・」
というようなプログラミングスタイルとは少し異なります。(勿論、厳密にはmainから始まる)

では、どのようなプログラムを書けばいいのか?
図示するとこのようになります。

calc5.jpg

簡単にいえば、iPhoneアプリというのは

1. ユーザが何かをする(ボタン押下、スライダ移動、フィンガジェスチャなど)
2. 対応するプログラムが走る
3. 画面が更新される

この3ステップから成り立っており、
ステップ2を設計することになります。
そう、それだけです。

普通は、アプリにはボタンや、スライダなどが複数配置されているため、
それぞれの部品に対応するプログラムが存在します。
それが、こんな感じ。

calc6.jpg

一番大切なのは、これだけです。
ボタンが押されたときにどうしたいか?それをプログラムに書くだけです。
スライダが動かされたときにどうしたいか?それをプログラムに書くだけです。

オブジェクト指向とか、デリゲートとか、
訳の分からない言葉は置いておいて、大切なのはこれだけです。

ユーザイベントに対して何を行うか?
それをプログラミングするだけです。



そして、

ユーザイベントに対応して駆動される関数にはIBActionをつける。
プログラム実行後、書き換えたいものにはIBOutletをつける。


これが、どこの入門書・入門サイトにも書いていないIBActionとIBOutletの意味です。


さて、なんか長くなってしまったので、今日はこのへんで。
次回こそはカウンタのプログラムを書きたいですね(笑)


はてなブックマークに追加

iPhoneアプリ・電卓をつくる その1




サイトを移行しました。
iPhoneアプリと、そのプログラム



これから数回にわたって電卓のiPhoneアプリを作っていきたいと思います。
単純に作業手順だけでなく、どうやって設計するのか?
まで伝えられたら良いかなと思ってます。

もとおもとはゼミの資料にする予定だったのですが、
せっかくなので公開しちゃおうということで(笑)

今回は難しいことは考えずに最小限の機能だけ実装していきましょう。
とりあえずの目標はiPhoneにデフォルトでついているこれ。

calc1.jpg

といっても、いきなりこれだけのものを作るのは大変だから、
もっと手前の段階からスタートして、徐々に電卓へと仕上げていきましょう。

ということで、電卓の前身であるカウンタから作っていきましょう。
雰囲気はこんな感じ。野鳥の会がもってるやつのディジタル版ですね(笑)
インタフェースはこんな感じ。

calc2.jpg

プラスボタンをタップしたら、数字がカウントアップされるという、
なんとも簡単なアプリです。
簡単ですが、iPhoneプログラミングに必要な要素はたくさん詰まっているので、
丁寧に見ていきたいと思います。


まずはプロジェクトを作成します。
Xcodeの「新規作成」-> 「ファイル」->「新規プロジェクト」を選択。
プロジェクトの種類「Application」でテンプレート「View-based Application」を選択。
プロジェクト名は「Calc1」にします。

まずはInterface Builderを使って、インタフェースを設計します。
左側にある「グループとファイル」カラムから「Resources」フォルダの中にある
「Calc1ViewController.xib」ファイルをダブルクリックしてください。
IBが起動し、4つのウインドウが開くと思います。

次に、Viewと書かれたウインドウにライブラリウインドウから
パーツをドラック&ドロップします。
今回は、次のように部品を配置してください。

calc3.jpg


配置できたら、UIButtonをダブルクリックして、ボタンの中に「+」を、
同様にUILabelをダブルクリックして「0」を記入してください。
また、UILabelのフォントを大きくしておきたいので、
Viewウインドウで一度Labelをクリックし、フォーカスを当てた状態で
インスペクタを次のように調整してください。

calc4.jpg


ここまでで、インタフェースの設計は一旦終了です。
次回はXcodeに戻ってプログラムを書いていきましょう。


iPhoneアプリ・電卓をつくる その2









はてなブックマークに追加

iPhoneアプリ開発のための参考書Top3


iPhoneアプリを作りたいんですけど、どの参考書で勉強したらいんですか?
という単純明快な問に対して、参考書マニアの僕が答えましょう(笑)

実は、大学の図書館に今発売されているiPhoneの参考書がほぼ揃っているんですね。
そして、僕はそれをすべて読んだわけですよw(さすが参考書マニア。別名暇人)
その上で、コレは読んどけ!を3冊ピックアップしてみましょう。


1冊目

iPhone SDKの教科書―Cocoa Touchプログラミング、最初の一歩
赤松 正行
秀和システム
売り上げランキング: 3045


これ以上の入門書は、もう出てこないんじゃあないかと思わせるぐらい
素晴らしい本です。僕のゼミでもテキストとして使用しています。
ゼミと言っても、この本を最初から最後まで5回読ませるというスパルタゼミですが(笑)

1周目は理解しながらプログラムを打つ、
2周目は考えながら、本を見ながら打つ、
3周目以降は打つべし!打つべし!打つべし!です(笑)

ゼミをやる方は、この本を使えばとっても楽ですよ☆
ゼミをやられる方は、この本を使えば天国と地獄が見えますよ☆


2冊目

Beginning iPhone 4 Development: Exploring the iOS SDK
David Mark Jack Nutting Jeff LaMarche
Apress
売り上げランキング: 63492


こちらも洋書ですが、文句なしの良書です。
日本語に訳された本が出ていますが、ゴミですので注意してください。

この本の特徴は洋書ならではの丁寧な説明。
日本の参考書みたく「ページの関係上割愛します」ってのがない。
洋書は分厚くなっても良いから丁寧に説明するという風潮があるようです。
ちなみに「ページの関係上割愛します」と書いてある参考書は大概、ゴミ予備軍です。
(僕の経験上w)

こちらはアプリにまで仕上げるというよりも
各部品の使い方や説明などが丁寧にされています。
上で紹介した「iPhone SDKの教科書」とあわせて読めば
鬼に金棒でしょう(表現がFULLすぎる)


あらら。
2冊紹介したところで、無敵になっちゃいましたね。
実際、この2冊+Appleのリファレンスがあればなんとかなります。
ということで、ページの関係上3冊目は割愛しますか(笑)



3冊目


iPhone SDK Programming Manual
iPhone SDK Programming Manual
posted with amazlet at 10.09.24
株式会社テクノロジックアート
ソーテック社
売り上げランキング: 282587



この本は上の2冊とはちょっと毛色が異なっていて
どちらかというとiPhoneアプリのバックグラウンドというか
InterfaceBuilderが裏で何をやっているかといった内容に重点をおいて書かれています。

こういう、他の参考書ではあまり紹介されていないところが
しっかり説明してあったので、おっ!と思ったわけです。
今、パラパラ見返してみたんですけどXMLパースのサンプルとか載ってますね(笑)

全くこの本を見ずに
iPhoneネットワークプログラミング その5
書いてましたがw


ということで、これが僕のオススメ参考書Top3でした。
3冊目はエキストラな感は否めませんが、読んでも絶対損はしない一冊になっています。
くれぐれも2冊目は洋書で読んでくださいね(くどい)



はてなブックマークに追加

iPhoneアプリ:RSSリーダを作る




サイトを移行しました。
iPhoneアプリと、そのプログラム



iPhoneネットワークプログラミングの第4回と第5回
iPhoneネットワークプログラミング その4
iPhoneネットワークプログラミング その5
のまとめとして、今度はRSSリーダを作ってみましょう。

今回作るRSSリーダは、
プログラム内にハードコーディングされたRSSフィードから情報を読み取り、
iPhone上に記事のタイトルを表示し、各記事のタイトルをタップすると
Safariでその記事が読める、という非常に高機能な仕上がり(笑)
役に立たない度合いは、前回作成した画像ビュアといい勝負w
iPhoneアプリ:画像ビュアを作る

完成図はこちらです。
今回はプログレスバーすらついておりませんが・・

rssreader1.jpg rssreader2.jpg


さて、ではXcodeで開発を進めていきます。
毎度おなじみの手順ですが、今回はプロジェクトの種類をNavigation-Basedで作成しています。

Xcodeの「新規作成」-> 「ファイル」->「新規プロジェクト」を選択。
プロジェクトの種類「Application」でテンプレート「Navigation-based Application」を選択。
プロジェクト名は「RssReader」にします。

今回はIB側での操作はありません。
早速、Xcodeにプログラムを書いていきましょう。
といっても、ほとんどが概出のものですので、理解はしやすいと思います。

RootViewController.h
@interface RootViewController : UITableViewController 
{
NSXMLParser * xmlParser;
NSMutableArray *titles, *links;

NSString *currentElement;
NSMutableString *currentTitle, *currentLink;
}
@end


今回のプログラムでは記事のタイトルの他に、記事へのURLが必要なので
第4回の内容に加えて、currentLinkという変数を追加しています。
また、記事のタイトル、URLをそれぞれtitles, linksという名前のNSMutableArray に格納します。
図示すればこんな感じです。

rssreader3.jpg

はい、まともなプログラマならNSDictionaryを使いますね(笑)
今回は、サンプルプログラムということで分かりやすさ優先で。

次にRootViewController.mにxml用のデリゲートメソッドを追加していきます。
内容は第4回とほぼ同じですね。
didEndElementのなかで、記事タイトルとURLをそれぞれの配列に格納しています。

- (void)viewDidLoad {
[super viewDidLoad];

NSURL *xmlURL = [NSURL URLWithString:@"http://iiphoneapp.blog51.fc2.com/?xml"];
xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];

// 領域確保
titles = [[NSMutableArray alloc] init];
links = [[NSMutableArray alloc] init];

// 各種設定
[xmlParser setDelegate:self];
[xmlParser parse];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];

if ([elementName isEqualToString:@"item"]) {
currentTitle = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:@"title"]) {
[currentTitle appendString:string];
} else if( [currentElement isEqualToString:@"link"]) {
[currentLink appendString:string];
}
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:@"item"]) {
[titles addObject:currentTitle];
[links addObject:currentLink];

[currentTitle release];
[currentLink release];
}
}


ここまでで、RSSのパースは完成です。次にTableViewの設定を行ないます。
下記の各プログラムをRootViewController.mに追加or編集してください。

まずは tableView:numberOfRowsInSectionメソッドを次のように変更してください。
ここでは、テーブルに格納する行数をタイトルの記事の数と指定しています。

- (NSInteger)tableView:(UITableView *)tableView 
numberOfRowsInSection:(NSInteger)section {
return [titles count];
}


次に、tableView:(cellForRowAtIndexPathメソッドの最後(return cell; の前)に
下記の2行を追加してください。このように記述することで、テーブルカラムに記事のタイトルを設定できます。

int index = [indexPath indexAtPosition: [indexPath length] - 1]; 
cell.textLabel.text = [titles objectAtIndex:index];



さて、最後にセルがタップされた時のアクションを設定します。
1行目でタップされたセルの行数をindexに格納します。
2行目でlinks配列から当該URLをとりだし
3行目で改行文字の削除
4行目でSafariを開いています。

- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int index = [indexPath indexAtPosition: [indexPath length] - 1];
NSString * link = [links objectAtIndex:index];

[link stringByPaddingToLength:([link length]-3) withString:@"" startingAtIndex:0];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:link]];
}


ここまで記述できたら、実行して動作するか確認してみてください。
なお、この記事作成にあたっては、ここを参考にさせていただきました。
あわせて御覧ください。

はてなブックマークに追加

iPhoneネットワークプログラミング その5




サイトを移行しました。
iPhoneアプリと、そのプログラム



第5回はiPhoneでXMLの解析をしてみたいと思います。

XMLの解析をするためには、XMLパーサが必要なのですが、
大きく分けて2種類のパーサが存在します。

それがDOM(Document Object Model)とSAX(Simple API for XML)です。
DOMでは、全てのXML情報を一度メモリに読み込み木構造に展開します。
それに対してSAXでは、シーケンシャルに情報を読み込んでいきます。
雰囲気的にはC言語でいうfgetsとgetcの違いみたいな感じです。

iPhoneではメモリの制約が厳しいため、DOMではメモリ不足が起こる可能性があります。
そこで、Cocoa標準のSAXパーサであるNSXMLParserクラスを使用します。

次に、RSSファイルのXMLの構造を見てみましょう。
itemタグで囲まれた部分が一つの記事に相当します。
ひとつの記事は、タイトル、概要、アドレス、更新日時などの情報から構成されています。

nsxmlparser1.jpg


ではNSXMLparserクラスを使って上のXMLを解析していきます。
View-Based ApplicationのViewControllerクラスにプログラムを追加していきます。

sampleViewController.h

@interface sampleViewController : UIViewController
{
NSXMLParser * xmlParser;
NSString * currentElement;
NSMutableString *currentTitle;
}
@end


sampleViewController.m

- (void)viewDidLoad {
[super viewDidLoad];

NSURL *xmlURL = [NSURL URLWithString:@"http://feeds.feedburner.com/TheAppleBlog"];
xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[xmlParser setDelegate:self];
[xmlParser parse];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:@"item"]) {
currentTitle = [[NSMutableString alloc] init];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:@"title"]) {
[currentTitle appendString:string];
}
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:@"item"]) {
NSLog(@"adding story: %@", currentTitle);
[currentTitle release];
}
}


viewDidLoadメソッドの中でNSXMLParserのインスタンスを作成し、
その初期化処理を行っています。具体的にはRSSのURL登録とデリゲートの設定です。
viewDidLoad以下の3つのメソッドがそのデリゲートメソッドになります。

まず一つめのデリゲートメソッドでitemタグの入りを見つけます。
itemタグが見つかればタイトルを格納するための文字列領域を確保します。

nsxmlparser2.jpg

2つ目のデリゲートメソッドで、実際のXMLファイルの解析をします。
今回のプログラムではタイトルの文字列を取得し、currentTitleに繋げていきます。
タイトルなどの文字列はサーバから一度に送られてくるわけではなく、分割されて送信されてくるので、
このように、iPhone側でappendStringを用いて再構成する必要があります。

nsxmlparser3.jpg

最後のデリゲートメソッドは解析終了時にコールされます。
今回のプログラムではここでタイトルを表示しています。

nsxmlparser4.jpg


実行してみて、実際にブラウザで見ることが出来るものと
タイトルが一致しているかどうか、確認してみてください。

はてなブックマークに追加

花化粧


flowers2.jpg

ディジタルな作品をひとつ作ってみたいなぁー、
と試行錯誤してみた。


参考書はこのへんを使用。

Collage Design Works Photoshop & Illustrator (CD-ROM付)
scrap-graphic
翔泳社
売り上げランキング: 42616


Photoshop+僕の実力ではこのへんが限界~。
スキャナで読み込んだ手書き素材使えばもう少しアナログ感が出るかも。
もすこしがんがる!たのしい!


こういう作品作るのって
目標もなければ、結論も、理論もゴールも答えもなーんもないわけですよ。
やってみてうまく行ったら、それでよし。
よくなる限り永遠に続けられるし、いつでもやめられる。
研究には無い楽しさがすべて詰め込まれている感じ。


はてなブックマークに追加

iPhoneネットワークプログラミング その4



サイトを移行しました。
iPhoneアプリと、そのプログラム



これまでは、一度にひとつのページしかダウンロードしませんでしたが、
ブラウザで同時に複数のタブを開くときなどには、
一度に複数のファイルをダウンロードする必要があります。

このように、一度に複数のHTTPリクエストを処理したい時には
NSOperationクラスを使用して、処理の流れを操作します。

NSOperationクラスはメソッド呼び出しなどを
独立した操作としてカプセル化するクラスであり、
通常はこのクラスのサブクラスを作成して使用します。

イメージ、こんな感じ。
nsoperation.jpg

下に、NSOperationを継承したサブクラスを示します。

RequestOperation.h
@interface RequestOperation : NSOperation {
NSURLRequest* _request;
NSMutableData* _data;
}
- (id)initWithRequest:(NSURLRequest *)request;
@end



RequestOperation.m
@implementation RequestOperation
- (id)initWithRequest:(NSURLRequest *)request {
if (self = [self init]) {
_request = [request retain];
_data = [[NSMutableData data] retain];
}
return self;
}

- (BOOL)isConcurrent {
return YES;
}

- (void)start {
if (![self isCancelled]) {
[NSURLConnection
connectionWithRequest:_request delegate:self];
}
}

- (void)connection:(NSURLConnection*)connection
didReceiveData:(NSData*)data {
[_data appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
NSLog(@"%@", [[NSString alloc] initWithData:_data
encoding:NSASCIIStringEncoding]);
}


- (void)dealloc {
[_request release];
[_data release];
[super dealloc];
}
@end


プログラムの内容は殆どの部分が、これまで書いてきたものを
NSOperationの中に詰め込んだだけになっています。
startとisConcurrentメソッドは、それぞれNSOperationクラスのもつ
メソッドをオーバライドしたものです。

startメソッドは処理の開始時に呼ばれるメソッドであり、
この中で、NSURLConnectionクラスの設定を行っています。
また、isConcurrentメソッドは非同期通信を行うかどうかの
フラグを返すメソッドであり、このプログラムではYESを返しています。

ここまでで、NSOperationのサブクラスは完成したので、
このクラスを呼び出して、複数HTTPリクエスト処理してみます。
ドライバプログラムはいつもどおりViewControllerのviewDidLoadメソッドの中に記述します。

SampleViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
_queue = [NSOperationQueue mainQueue];

NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
RequestOperation* operation = [[RequestOperation alloc] initWithRequest:request];
[operation autorelease];

NSURLRequest* request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.yahoo.co.jp"]];
RequestOperation* operation2 = [[RequestOperation alloc] initWithRequest:request2];
[operation2 autorelease];

[_queue addOperation:operation];
}


はじめに、処理を追加する待ち行列NSOperationQueueを作成しています。
次に、2つのHTTPリクエストを作成し、先程作成したQueueに追加します。
これで、実行すれば自動的にリクエストが順番に処理されていきます。

次回はXMLのパースについてのおはなし
iPhoneネットワークプログラミング その5

開発アプリ

iDOF 色影 ラテアート ぱすてる

プロフィール

hokuson

Author:hokuson
京都在住。iPhoneアプリ「色影」や「iDOF」の開発者。アプリのレビューとかもしてみる。博士後期課程@R大学。ついに就職活動なるものをしなければいけないらしい。誰か雇ってください。笑。

カレンダー
07 | 2017/08 | 09
- - 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 - -
カテゴリ
最新コメント
RSSリンクの表示
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。