2012-02-11 6 views
0

ビューコントローラでNSURLConnection非同期メソッド呼び出しを呼び出しています。私は同じ代議員に2つのリクエストに対する2つの返答を処理したいと思います。これを達成するための最良の方法は何ですか?私はiOS 5 SDKで開発中です。iPhone:同じデリゲートの2つのリクエストに対して2つ(または複数)のレスポンスを処理します

更新日:

// Class A 
[serverconns setDelegate:self]; 
connection = [serverconns executeAsyncHttpPost :firstjsonrequest]; 

[serverconns setDelegate:self]; 
connection = [serverconns executeAsyncHttpPost :secondjsonrequest]; 


- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
} 

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

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    // logs the error 
} 

- (void) connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    NSData *responseData = [[NSData alloc] initWithData:appendData]; 
    //HOW CAN WE HANDLE TWO RESPONSES FOR TWO REQUEST in the same Delegate 
    if (responseData) 
    { 
      // doing something 
    } 
} 

    //Class B: ServerConnection 

- (NSURLConnection *) executeAsyncHttpPost :(id) jsonParams 
{ 
    NSString *urlstr = [NSString stringWithFormat:@"%@", baseURL]; 
    urlstr = [urlstr stringByAppendingFormat:method]; 

    NSURL *pUrl = [NSURL URLWithString:urlstr]; 

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:pUrl]; 
    NSData *requestData = [NSData dataWithBytes:[jsonParams UTF8String] length:[jsonParams length]]; 

    [request setHTTPMethod:@"POST"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-type"]; 
    [request setHTTPBody: requestData]; 

    return [[NSURLConnection alloc] initWithRequest:request delegate:delegateResponder startImmediately:YES]; 

} 
    -(void) setDelegate:(id)newDelegate 
{ 
    delegateResponder = newDelegate; 
} 

答えて

2

)接続を作成し、私があなただったら、私はCustomClassを作成しますNSURLConnectionを継承します。タグと呼ばれるプロパティを追加します。

私はCustomClassを開始すると、私は、タグのプロパティを設定して、今、あなたはこの

- (void) connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    NSData *responseData = [[NSData alloc] initWithData:appendData]; 
    //HOW CAN WE HANDLE TWO RESPONSES FOR TWO REQUEST in the same Delegate 
    if (responseData) 
    { 
     if (connection.tag == 1){ 

     } 
    } 
} 

return self; 
    } 
+0

私は== 'if(connection.tag == @" Conn A ")' –

+0

を使って比較することをお勧めします。それを指摘してくれてありがとう。 intに変更されました。基本的にASIHTTPRequest – mbh

+0

からアイデアを作り直そうとしていました。でも、上のコードを更新してください。私は2つのクラスを使用しています。デリゲートメソッドは別のファイルにあります。あなたはまだあなたの提案を進めることができると思いますか? – Getsy

0

私は通常、NSURLConnectionをサブクラス化して、私は応答を処理する必要がどのような文脈格納するプロパティを追加します。

代理メソッドは渡されたNSURLConnectionを取得するので、それをサブクラスにキャストしてコンテキストにアクセスすることができます。

this exampleをご覧ください。

+0

この例では正しく機能しません。私の更新されたコードを見てください、私は、リクエストクラスではなく、呼び出し元からデリゲートメソッドを持っています。 – Getsy

3

NSString *urlstr = [baseURL absoluteString]; 
urlstr = [urlstr stringByAppendingString:method]; 
に置き換える必要がありますちょうど

NSString *urlstr = [NSString stringWithFormat:@"%@", baseURL]; 
urlstr = [urlstr stringByAppendingFormat:method]; 

あなたのコードのいくつかのマイナーな問題を指摘

- (void) connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    NSData *responseData = [[NSData alloc] initWithData:appendData]; 
    //HOW CAN WE HANDLE TWO RESPONSES FOR TWO REQUEST in the same Delegate 
    if (responseData) 
    { 
     if (connection == yourFirstConnection) { 
      // doing something for first connection 
     } else { 
      // doing something for second connection 
     } 
    } 
} 

(デリゲートの多分IVAR)どこかの接続を保存します

と2つ(またはより多くのまたは配列)弱い/あなたのクラスAにNSURLConnectionのプロパティを割り当てる(接続デリゲート)あなたのクラスBよりも

@property (assign) NSURLConnection *myFirstConnection; 
@property (assign) NSURLConnection *mySecondConnection; 
// assume only need to handle two connection otherwise NSArray should be used instead 

- (NSURLConnection *) executeAsyncHttpPost :(id) jsonParams 
{ 
    NSString *urlstr = [baseURL absoluteString]; 
    urlstr = [urlstr stringByAppendingString:method]; 

    NSURL *pUrl = [NSURL URLWithString:urlstr]; 

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:pUrl]; 
    NSData *requestData = [NSData dataWithBytes:[jsonParams UTF8String] length:[jsonParams length]]; 

    [request setHTTPMethod:@"POST"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-type"]; 
    [request setHTTPBody: requestData]; 

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegateResponder startImmediately:YES]; 
    delegateResponder.myFirstConnection = connection; 
    // delegateResponder.mSecondConnection = connection; 
    return connection; 

} 
+0

+1、この場合は最も簡単な解決策です。 – tipycalFlow

+0

OK ..しかし、上記のコードを更新してください。私は2つのクラスを使用しています。あなたはまだ考えている、私は2つの異なるNSURLConnectionオブジェクトを作成し、後で使用することができますか? – Getsy

+0

宣言していても、プロパティmyFirstConnectionは見つかりませんでした。また、どのようにして2番目の条件を追加することができますか? – Getsy

1

Iを追加掲載コードで

CustomURLConnection *connection = [[CustomURLConnection alloc] initWithRequest:request delegate:self tag:1]; 

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate tag:(int)_tag 
{ 
if(self = [super initWithRequest:request delegate:delegate]) 
{ 
    self.tag = _tag; 
} 

で働いされている要求を決定するためにそれを使用します言及されたすべてのソリューションが「醜い」と思う。デリゲートメソッドを使用したソリューションを実装するのではなく、代わりにブロックベースのソリューションを作成します。あなたが興味を持っているなら、私は例を投稿することができます。私はこのアプローチのためにAFNetworkingクラスを利用するでしょう。


以下はAFNetworkingライブラリと代わりにブロックを選ぶ、デリゲートの実装を使用せずに、2つの異なる応答を処理するクラスの例です。

- (void)JSONFromService 
{ 
    // create the first request and set the methods that handle the return values (either NSData or NSError in this case) in blocks ... 

    NSURL *firstURL = [NSURL URLWithString:@"http://dl.dropbox.com/u/6487838/test1.html"]; 
    NSURLRequest *firstRequest = [NSURLRequest requestWithURL:firstURL]; 
    AFHTTPRequestOperation *firstOperation = [[AFHTTPRequestOperation alloc] initWithRequest:firstRequest]; 

    [firstOperation setCompletionBlockWithSuccess:^ (AFHTTPRequestOperation *operation, id object) 
    { 
     NSString *firstString = [[NSString alloc] initWithData:object encoding:NSASCIIStringEncoding]; 
     NSLog(@"%@", firstString); 
    } failure:^ (AFHTTPRequestOperation *operation, NSError *error) { 
     NSLog(@"%@", error); 
    }]; 
    [firstOperation start]; 



    // create the second request and set the methods that handle the return values (either NSData or NSError in this case) in blocks ... 

    NSURL *secondURL = [NSURL URLWithString:@"http://dl.dropbox.com/u/6487838/test2.html"]; 
    NSURLRequest *secondRequest = [NSURLRequest requestWithURL:secondURL]; 
    AFHTTPRequestOperation *secondOperation = [[AFHTTPRequestOperation alloc] initWithRequest:secondRequest]; 

    [secondOperation setCompletionBlockWithSuccess:^ (AFHTTPRequestOperation *operation, id object) { 
     NSString *secondString = [[NSString alloc] initWithData:object encoding:NSASCIIStringEncoding]; 
     NSLog(@"%@", secondString); 
    } failure:^ (AFHTTPRequestOperation *operation, NSError *error) { 
     NSLog(@"%@", error); 
    }]; 
    [secondOperation start]; 
} 
+0

投稿してください。 – Getsy

0

すべての接続をactiveConnectionsの配列に保持する必要があります。 1つが終了するたびに[activeConnections indexForObject:connection]を実行し、インデックスを使用してデリゲートメソッドを更新します。

ここでは、よりクリーンな方法(と私の観点からはより良い方法ですが、これは転送するデータの量によって異なります)はキューを使用することです。私は小さな例を提供し、それにコメントを追加します:

// we assume you have 2 requests: req1, req2 

//now, create a new dispatch queue  
dispatch_queue_t netQueue = dispatch_queue_create("com.mycompany.netqueue",DISPATCH_QUEUE_SERIAL); 

//execute the operations in the queue ASYNC 
//is very important to dispatch this ASYNC on a background thread, otherwise your UI will be stuck until the request finishes 
dispatch_async(netQueue, 
^{ 
    // We are on a background thread, so we won't block UI events (or, generally, the main run loop) 
    NSHTTPURLResponse *response = nil; 
    NSError *error = nil; 
    NSData *data = nil; 




    //We can call the request synchronous and block this thread until completed 
    data = [NSURLConnection sendSynchronousRequest:req1 
           returningResponse:&response 
              error:&error]; 

    dispatch_async(dispatch_get_main_queue(), 
    ^{ 
    //call your delegate with the appropriate method for req1 
    //be sure to copy the contents in data, as we will reuse it with the next request 
    }); 

    //We can call the other request synchronous and block this thread until completed 
    data = [NSURLConnection sendSynchronousRequest:req2 
           returningResponse:&response 
              error:&error]; 
    dispatch_async(dispatch_get_main_queue(), 
    ^{ 
    //call your delegate with the appropriate method for req2 
    }); 




    //and this can go on forever. If you have many requests to execute, simply put them in a loop 


}); 
dispatch_release(netQueue); 
+0

マインは非同期で同期していません。 – Getsy

+0

これも非同期で、バックグラウンドスレッドで実行されます。 –

+0

OK、ありがとうございます。私のコードはあなたの提案に基づいて変更することができますか? – Getsy

関連する問題