对于NSURLConnection在5.0后有两种方法实现异步请求,一种是5.0以后引入的+sendAsynchronousRequest:queue:completionHandler:
,还有就是2.0就存在的+connectionWithRequest: delegate:
。前一种方法当然是最方便的,而且文档全。但是考虑到兼容的问题,往往还是会采用后者,但是问题在于文档的不全,会让人引起混乱,尽管有一个例子SimpleURLConnection的例子。
+sendAsynchronousRequest:queue:completionHandler:
- (void)loadDataSource {
NSString *URLPath = [NSString stringWithFormat:@"http://imgur.com/gallery.json"];
NSURL *URL = [NSURL URLWithString:URLPath];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
if (!error && responseCode == 200) {
id res = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if (res && [res isKindOfClass:[NSDictionary class]]) {
self.items = [res objectForKey:@"gallery"];
[self dataSourceDidLoad];
} else {
[self dataSourceDidError];
}
} else {
[self dataSourceDidError];
}
}];
}
+connectionWithRequest: delegate:
- (void)loadDataSource {
NSString *URLPath = [NSString stringWithFormat:@"http://imgur.com/gallery.json"];
NSURL *URL = [NSURL URLWithString:URLPath];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[NSURLConnection connectionWithRequest:request delegate:self];
}
//---------------------------------------
// You have to implement below four methods
//---------------------------------------
- (void)connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response
{
NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
_connectedSuccess = responseCode == 200;
NSLog(@"response length=%lld", [response expectedContentLength]);
}
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
// A delegate method called by the NSURLConnection as data arrives. The
// response data for a POST is only for useful for debugging purposes,
// so we just drop it on the floor.
{
if (_galleryData == nil) {
_galleryData = [[NSMutableData alloc] initWithData:data];
} else {
[_galleryData appendData:data];
}
}
- (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error
// A delegate method called by the NSURLConnection if the connection fails.
// We shut down the connection and display the failure. Production quality code
// would either display or log the actual error.
{
}
- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection
// A delegate method called by the NSURLConnection when the connection has been
// done successfully. We shut down the connection with a nil status, which
// causes the image to be displayed.
{
if (_connectedSuccess) {
id res = [NSJSONSerialization JSONObjectWithData:_galleryData options:NSJSONReadingMutableContainers error:nil];
if (res && [res isKindOfClass:[NSDictionary class]]) {
self.items = [res objectForKey:@"gallery"];
[self dataSourceDidLoad];
} else {
[self dataSourceDidError];
}
[_galleryData release];
_galleryData = nil;
} else {
[self dataSourceDidError];
}
}
实际上必须要实现NSURLConnectionDataDelegate,而这个Protocol的声明在文档中是不容易找到的,只有在这里提到了一下,在SimpleURLConnection中则没有说清楚。不过估计在5.0以前应该是没有这个Protocol的,所以在实现的过程中只要增加这四个方法就可以了,也可以有选择性地增加你想要地因为都是可选地方法。注意在这个代码里面用到了NSJSONSerialization,这个也是5.0引入的,所以要想用JSON Parser可以考虑JSONKit。