Hatena::Groupiphone-dev

haoyayoi Dev Style このページをアンテナに追加 RSSフィード

2009-07-18

ImageStoreの画像取得失敗時対処

| 03:48 | ImageStoreの画像取得失敗時対処 - haoyayoi Dev Style を含むブックマーク はてなブックマーク - ImageStoreの画像取得失敗時対処 - haoyayoi Dev Style ImageStoreの画像取得失敗時対処 - haoyayoi Dev Style のブックマークコメント

ImageStoreを使ってクライアントを作っていたのですが、画像取得時に503や404が返ってきた場合でも正常なダウンロードとみなされていたようで、UIImageのメモリ操作時にエラーで落ちることがありました。

HttpClientのconnection:didReceiveResponse:にて、データ詳細の如何(imageではなくtextだった等)に関わらず成功として扱われるのが原因だった様子。とりあえずContent-Typeでimageでは無かった場合にconnection:didFailWithError:へ投げることで対処。

HttpClient.m

- (void)connection:(NSURLConnection*)sender didReceiveResponse:(NSHTTPURLResponse*)aResponse
{
	[response release];
+	NSDictionary *resHead = [aResponse allHeaderFields];
+	NSString *contenttype = [resHead objectForKey:@"Content-Type"];
+	NSArray *datatype = [[contenttype componentsSeparatedByString:@"/"] objectAtIndex:0];
+	if([datatype isEqual:@"image"]){
		response = [aResponse retain];
+	}else{
+		[self connection:sender didFailWithError:nil];
+	}
}

connection:didFailWithError:に投げる代わりに、エラー時代替イメージのNSDataを差し込むようにしむけるのもありです。

iwadoniwadon2009/07/18 12:46フィードには以下のものがあるように見えますがいかがでしょうか。
http://iphone-rejectdb.appspot.com/feed?format=rss2
http://iphone-rejectdb.appspot.com/feed?format=atom

hao_yayoihao_yayoi2009/07/18 20:14feed存在してました。しかもなんか購読してたっぽいです。
未読の中に埋もれてたので、弄って読みやすくすることにします…。

2009-06-27

ImageStoreのコードリーディング

| 10:45 | ImageStoreのコードリーディング - haoyayoi Dev Style を含むブックマーク はてなブックマーク - ImageStoreのコードリーディング - haoyayoi Dev Style ImageStoreのコードリーディング - haoyayoi Dev Style のブックマークコメント

ImageStoreは画像ダウンロードにおいて使い勝手のいいフレームワークです。使い方も開発者自身が提示しているので迷いません。

実際にはこんな感じ。


#import "ImageStore.h"

//-------------(途中略)

- (void)viewDidLoad {
    [super viewDidLoad];

    imageStore = [[ImageStore alloc] initWithDelegate:self];
    [imageStore getImage:@"http://assets0.twitter.com/images/twitter_logo_header.png"];
}

- (void)imageStoreDidGetNewImage:(ImageStore*)sender url:(NSString*)url
{
    UIImage* image = [sender getImage:url];
    // 画像を使う処理
}

ただ、ここまで使い勝手がいいとなると、どんな処理がなされているか気になるものです。そこで、勉強がてらにコードリーディング

構成

ImageStoreは、

  • HttpClient
  • ImageDownloader
  • ImageStore
  • StringHelper

の4つのクラスで構成されています。

HttpClient

実際に画像をダウンロードするクラスです。delegateメソッドとしてNSObjectにHttpClientDelegateカテゴリを構成します。NSURLRequestの結果に応じてHttpClientDelegateカテゴリ内のメソッドを実行します。

ImageDownloader

HttpClientをラップするクラスです。delegateメソッドとしてNSObjectにImageDownloaderDelegateカテゴリを構成します。HttpClientの結果に応じてImageDownloaderDelegateカテゴリ内のメソッドを実行します。

ImageStore

Developerが実際に触れるクラスです。ImageDownloaderをラップしています。delegateメソッドとして、ImageStoreにPrivateカテゴリを構成します。DeveloperはPrivateカテゴリのメソッド内にて実際に取得した画像に対する処理を行います。

StringHelper

HttpClient内にて、URLRequestの際のクエリを組み立てる時に用いられるクラスです。

処理の実際

各クラス同士は以下のような具合にやり取りしています。

f:id:hao_yayoi:20090627103356p:image

プロトコルでは無い理由

プロトコル化することで、NSObjectを汚染せずにコーディングすることも可能です。ImageStoreの場合はあえてNSObjectにいれることで、コーディングに掛かる工数を減らしています。

paellapaella2009/06/27 19:50すばらしいです。このフレームワークは気になっていたので、とても参考になりました。

hao_yayoihao_yayoi2009/06/28 19:56いつかやろうと思いつつ全然やっていなかったので、片付ける感じでやっちゃいました。
delegateメソッドで幾つか用いられていないものがあったので、そこらへんをもうちょっと踏み込み必要みたいです。

PsychsPsychs2009/06/30 14:12delegate に用いる protocol は、informal protocol にするのが一般的です。formal protocol にすると、delegate オブジェクトは、protocol に含まれるすべてのメソッドを実装する必要があるからです。

hao_yayoihao_yayoi2009/07/12 11:43レス遅れてしまってすいません。

informal protocolについては、SDKのヘッダを見ていて「なんか書かれてるー」という程度の認識で、以前protocolを作ろうとしたとき、そこらへん分かってなくて全部formalにしちゃってました。まだまだ学習の余地ありです。