2013-08-27 102 views
1

我試圖通過提取一個URL來填充UITableView。爲了避免凍結用戶界面我使用dispatch_async(dispatch_queue_t queue, ^(void)block)製作異步提取。 在使用NSRunLoop等待響應的異步塊中。如何等待異步NSURLConnection響應

這裏是我取代碼:

- (BOOL)isFinished { 
    return _finished; 
} 

- (void)startReceive { 
    NSURLRequest* request = [NSURLRequest requestWithURL:self.baseURL]; 
    self.connection = [NSURLConnection connectionWithRequest:request delegate:self]; 
    assert(self.connection); 
} 

- (void)stopReceiveWithStatus:(NSString*)statusCode { 
    if (self.connection) { 
     [self.connection cancel]; 
     self.connection = nil; 
    } 
    self.finished = YES; 
    NSLog(@"Stop Receive with status code %@", statusCode); 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    assert(connection == self.connection); 
    NSHTTPURLResponse* httpResponse = nil; 
    if ([response isKindOfClass:[NSHTTPURLResponse class]]) { 
     httpResponse = (NSHTTPURLResponse*) response; 

     if (httpResponse.statusCode != 409) { 
      // I need 409 to fetch some data 
      [self stopReceiveWithStatus:[NSString stringWithFormat:@"HTTP error %2d", httpResponse.statusCode]]; 
     } 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    assert(connection == self.connection); 
    self.sessionID = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    assert(connection == self.connection); 

    [self stopReceiveWithStatus:@"Connection failed"]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    assert(connection == self.connection); 

    [self stopReceiveWithStatus:nil]; 
} 

的UITableViewController:

// refreshControl handler 
- (IBAction)refresh { 
    [self startRefreshingAnimation]; 
    dispatch_queue_t loaderQ = dispatch_queue_create("loading transmission data", NULL); 
    dispatch_async(loaderQ, ^{ 
     [self foo]; 
     while(!self.t.finished) { 
      [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
     } 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self endRefreshingAnimation]; // end 
     }); 
    }); 
} 

- (void)foo { 
    NSLog(@"session id: %@", self.t.sessionID); 
} 

這時候,HTTP請求已經做sessionID將被填充。現在的問題是我第一次打電話時無法獲得sessionID,因爲第一次沒有填充,第二次沒有問題。第一次打電話時我怎樣才能得到它?

我是iOS新手。如果你有更好的解決方案來解決這個問題,請告訴我,謝謝。

+0

最後,我把'NSRunLoop'在會話ID的getter確保sessionID填充 – Pikaurd

回答

0

有一個很好的框架,不要浪費你的時間。

https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking

Upd。 你可以做你的要求,如:

NSURL *url = self.baseURL; 
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url]; 

NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: 
        height, @"user[height]", 
        weight, @"user[weight]", 
        nil]; 
[httpClient postPath:@"/myobject" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { 
NSString *responseStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; 
NSLog(@"Request Successful, response '%@'", responseStr); 
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
NSLog(@"[HTTPClient Error]: %@", error.localizedDescription); 
}]; 
0

您應該使用第三方庫來處理網絡連接,如STHTTPRequest

STHTTPRequest *r = [STHTTPRequest requestWithURLString:@"http://www.apple.com"]; 

r.completionBlock = ^(NSDictionary *headers, NSString *body) { 
    // ... 
}; 

r.errorBlock = ^(NSError *error) { 
    // ... 
}; 

[r startAsynchronous];