2013-08-27 103 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];