One simple方法是使用NSURLConnection
的便捷类方法sendAsynchronousRequest:queue:error
.
以下代码片段是如何从服务器加载 JSON 以及完成处理程序在解析 JSON 的后台线程上执行的示例。它还执行所有建议的错误检查:
NSURL* url = [NSURL URLWithString:@"http://example.com"];
NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest addValue:@"application/json" forHTTPHeaderField:@"Accept"];
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:queue
completionHandler:^(NSURLResponse* response,
NSData* data,
NSError* error)
{
if (data) {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
// check status code and possibly MIME type (which shall start with "application/json"):
NSRange range = [response.MIMEType rangeOfString:@"application/json"];
if (httpResponse.statusCode == 200 /* OK */ && range.length != 0) {
NSError* error;
id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (jsonObject) {
dispatch_async(dispatch_get_main_queue(), ^{
// self.model = jsonObject;
NSLog(@"jsonObject: %@", jsonObject);
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
//[self handleError:error];
NSLog(@"ERROR: %@", error);
});
}
}
else {
// status code indicates error, or didn't receive type of data requested
NSString* desc = [[NSString alloc] initWithFormat:@"HTTP Request failed with status code: %d (%@)",
(int)(httpResponse.statusCode),
[NSHTTPURLResponse localizedStringForStatusCode:httpResponse.statusCode]];
NSError* error = [NSError errorWithDomain:@"HTTP Request"
code:-1000
userInfo:@{NSLocalizedDescriptionKey: desc}];
dispatch_async(dispatch_get_main_queue(), ^{
//[self handleError:error]; // execute on main thread!
NSLog(@"ERROR: %@", error);
});
}
}
else {
// request failed - error contains info about the failure
dispatch_async(dispatch_get_main_queue(), ^{
//[self handleError:error]; // execute on main thread!
NSLog(@"ERROR: %@", error);
});
}
}];
尽管看起来有些复杂,但在我看来,这是一种简约且仍然幼稚的方法。除其他缺点外,主要问题是:
- 它无法取消请求,并且
- 没有办法处理更复杂的身份验证。
需要利用更复杂的方法NSURLConnection
代表们。通常,第三方库确实以这种方式实现它,封装了NSURLConnection
请求和其他相关状态信息放入子类中NSOperation
。您可以从自己的实现开始,例如使用这段代码 https://gist.github.com/couchdeveloper/5764723作为模板。