Results tagged “Objective-c” from chikathreesix

【iPhone】NSURLConnectionのエラーハンドリング

|
久しぶりに技術ネタ。
iPhoneでRSSを読み込むやつを作ってるんだけど、NSURLConnectionのエラーハンドリングってどうすればいいのかいまいち分からなかったのでまとめます。



まずNSURLConnectionのdelegateには主に以下のメソッドがあります。

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
HTTPヘッダーを取得したら呼び出される

-(void) connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
データを取得するたびに呼び出される

-(void)connectionDidFinishLoading:(NSURLConnection*)connection
データの取得がすべて終了したら呼び出される

-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
エラーが発生した場合に呼び出される




さて、エラーについては大まかに以下のものが考えられると思います。

1) URLが間違っている(ドメイン部分が間違っている) 
2) URLが間違っている(ドメイン以下が間違っている)
3) そもそもネットワークが利用できない状況
4) その他


4)は置いておいて、ひとつづつ見ていこうと思います。


1) URLが間違っている(ドメイン部分が間違っている)
→他のdelegateメソッドは呼ばれずに、didFailWithErrorが呼ばれる。

2) URLが間違っている(ドメイン以下が間違っている)
→404のレスポンスを受け取るため、didFailWithErrorは呼ばれずに他のdelegateメソッドが呼ばれる。

3) そもそもネットワークが利用できない状況
→他のdelegateメソッドは呼ばれずに、didFailWithErrorが呼ばれる。



以上からエラーハンドリングをする箇所が二カ所必要であることが分かります。

1. didReceiveResponse内でhtmlヘッダのチェック
2. didFailWithError内でのエラーチェック



ではどのように実装するか。

1. didReceiveResponse内でhtmlヘッダのチェック
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
	int statusCode = [((NSHTTPURLResponse *)response) statusCode];
	if(statusCode >= 400){
		//エラーハンドリング
	}
}
didRecieveResponse内でヘッダを取得し、値に応じてエラーハンドリングします。


2. didFailWithError内でのエラーチェック
-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error{
	NSLog(@"Connection failed! Error - %@ %d %@",
		  [error domain],
		  [error code],
          [error localizedDescription]);
	
	//ネットワークに接続されていない時
	if([error code] ==  NSURLErrorNotConnectedToInternet){
		[self cancelByConnection];
		return;
	}
}
上記ソースではネットワークに接続されていない時のエラーしかハンドリングしてませんが、
[error code]をNSURLErrorの定数で振り分けることでハンドリング可能です。

didFailWithError内でどうエラーハンドリングすればいいか、なかなか情報がなくて苦労しました。。

【iPhone】 キー値監視について

|
久しぶりにObjective-Cをいじった。
マイコミの記事を参考にしていたんだけど、addObserverってのが出てきてハマった。。。

厳密には違うけど、ASで言うところのaddEventListener的な使い方ができる。
NSObjectで実装されているので、なんかしらのクラスを継承してれば使えるっぽい。

タイトルの「キー値監視」とは、あるオブジェクトのプロパティの値が変化した事を他のオブジェクトに通知すること。
addObserverはその変化の通知を受け取るオブザーバを登録する際に利用するメソッドのようだ。




キー値監視を行うには、
1、addObserverで監視対象のオブジェクト、監視したいプロパティ、監視するオブジェクトを監視されるオブジェクトに登録。
メソッドは以下。

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context

・observer
イベントを受け取る人。通知を受け取るobserveValueForKeyPathというデリゲートメソッドを実装しておく必要がある。

・forKeyPath
いろんなところで「キー値」だとかいう説明がされてたけど、要はイベントを発行するオブジェクトのプロパティ名だと思う。「キー値」じゃなんだかわかんねーっつーのw

・options
変化する前の値を受け取るか、変化した後の値を受け取るか

・context
なんだかわからないっすw


2、オブザーバにてプロパティの変化を受け取るメソッドを定義
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object
                        change:(NSDictionary*)change context:(void*)context


3、setValueを使ってプロパティの値を変更する




これでできるはずなんだけど、どうやらデフォルトで自動通知がオフになっているらしいので、以下メソッドをオーバーライドしてYESを返す必要があるみたい。

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key
{
	if ([key isEqualToString:@"isFinished"])
       {
		return YES;
	}
	
	return [super automaticallyNotifiesObserversForKey:key];
}


特定のキー値の時YESを返すって感じです。

Archives