태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

mobile/ios2010/06/10 17:21

NSURLConnection을 이용하여 서버와 데이터 통신을 하였다.

처음에는 Single asynchronous Commuication 으로 작업을했는데, 비정상적인 상황(네트워크 지연, 에러 등,,,)에서 데이터가 이상하게 들어오는 현상이 있었다.

분석을 해보니, 하나의 커넥션으로 서버에 여러 요청을 하고, 서버의 응답을 하나의 데이터(NSMutableData) 에 appendData 를 해서 발생하는 문제였다.

그러면, 멀티 비동기 통신을 지원해야한다는 이야기인데, (사실, 당연히 이렇게 했어야했는데, 시뮬레이터로 테스트를 하니 문제가 없길래 -_-) 여러가지 방법을 찾아보고, 생각해 보았다.

그러다가 다음 블로그에서 찾은 내용을 이용해 보기로 했다.
http://blog.emmerinc.be/index.php/2009/03/15/multiple-async-nsurlconnections-example/

내용은 다음과 같다.
NSURLConnection 을 상속받는 CustomNSURLConnection 을 만든다.

그런뒤, 생성자에서 각 커넥션을 구분할수 있는 tag를 받고, 각 Connection 객체를 tag로 관리하는 것이다.

delegate method 인 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

를 보면 Connection을 argument로 받으니,  CustomNSURLConnection 으로 casting 해서, tag값을 뽑아 구분한다는 이야기이다.

가장 심플하고 정확한 방법인 듯하다.

실제 소스를 보자,

NSURLConnection를 상속받는 CustomURLConnection 를 만들자.

[CustomURLConnection.h]

@interface CustomURLConnection : NSURLConnection {
   NSString *tag;
}
 
@property (nonatomic, retain) NSString *tag;
 
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)tag;
 
@end



implementation:

[CustomURLConnection.m]

@implementation CustomURLConnection
 
@synthesize tag;
 
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)tag {
   self = [super initWithRequest:request delegate:delegate startImmediately:startImmediately];
 
   if (self) {
      self.tag = tag;
   }
   return self;
}
 
- (void)dealloc {
   [tag release];
   [super dealloc];
}
 
@end


header file에 각 connection에서 받은 데이터를 저장하기위해 NSMutableDictionary 를 선언한다.

NSMutableDictionary *receivedData;

- (void)startAsyncLoad:(NSURL*)url tag:(NSString*)tag {
   NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
   CustomURLConnection *connection = [[CustomURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES tag:tag];
 
   if (connection) {
      [receivedData setObject:[[NSMutableData data] retain] forKey:connection.tag];
   }
}
 
- (NSMutableData*)dataForConnection:(CustomURLConnection*)connection {
   NSMutableData *data = [receivedData objectForKey:connection.tag];
   return data;
}
 
- (void)load {
   receivedData = [[NSMutableDictionary alloc] init];
 
   NSURL *url1 = [NSURL URLWithString:@"http://blog.emmerinc.be"];
   NSURL *url2 = [NSURL URLWithString:@"http://www.emmerinc.be"];
   NSURL *url3 = [NSURL URLWithString:@"http://twitter.com/emmerinc"]; 
 
   [self startAsyncLoad:url1 tag:@"tag1"];
   [self startAsyncLoad:url2 tag:@"tag2"];
   [self startAsyncLoad:url3 tag:@"tag3"];
}
 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
   NSMutableData *dataForConnection = [self dataForConnection:(CustomURLConnection*)connection];
   [dataForConnection setLength:0];
}
 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
   NSMutableData *dataForConnection = [self dataForConnection:(CustomURLConnection*)connection];
   [dataForConnection appendData:data];
}
 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
   NSMutableData *dataForConnection = [self dataForConnection:(CustomURLConnection*)connection];
   [connection release];
 
   // Do something with the dataForConnection.
}


꽤 간단하다.

^^
Posted by THLIFE.net

TRACKBACK http://thlife.net/trackback/1020 관련글 쓰기

댓글을 달아 주세요