(一) 概述
URL Loading System 提供了访问URL指向的server端内容的能力,核心就是NSURL类。该系统提供:下载、上传、管理cookie、缓存、认证以及编写定制的协议扩展。
该系统支持以下协议:ftp://,http://,https://,file:///,data://。
(另外,iOS提供了用safari打开网页的方法,参见UIApplication的openURL:)
(二)框架图
1. URL Loading 概览
1)iOS 7 以及以后的版本,最好用NSURLSession来做URL request。
2)如果为了支持旧版本,可以用NSURLConnection来做,下载URL内容到内存(如需要,可写入硬盘)。
2. 获取内容到内存(in-memory)
1)对于简单的情况,用 NSURLSession +NSURL 就够了。
2)对于复杂情况,比如上传数据,用 NSURLSession +NSURLRequest 或者 NSURLConnection +NSURLRequest 就够了。
无论是那种方式,获取response都有两种方法:a)设置一个callback的block;b)设置一个delegate。
3. 获取内容到硬盘(on-disk)
1)对于简单的情况,用 NSURLSession +NSURL 就够了。
2)对于复杂情况,用 NSURLSession +NSURLRequest 或者 NSURLDownload +NSURLRequest 就够了。
注意:NSURLSession 比 NSURLDownload 有优势:NSURLSession可以一直下载,即使你的app被挂起了、kill掉了、或者崩溃了也不影响下载。
(三)编程API
有两种方式:NSURLSession,NSURLConnection,但NSURLConnection用起来相对简单一些。
1. 用 NSURLConnection
a)同步方式:sendSynchronousRequest:returningResponse:error:
b)异步block方式:sendAsynchronousRequest:queue:completionHandler:
c)异步delegate方式:NSURLConnectionDelegate,NSURLConnectionDownloadDelegate,NSURLConnectionDataDelegate
2. 用NSURLSession
NSURLSession比NSURLConnection爽的地方,就在于当app没有运行(挂起、终止、崩溃)的时候,依然可以在后台下载、上传。这种方式实际上是把下载任务让另外一个独立的进程干了。当下载完成后,系统就在后台启动app,并传给相应的参数以接收数据。这一部分不详细说了,可以参考资料:
(四)常用代码
1. 用 NSURLConnection 访问 URL
NSString *urlAsString = @"http://www.cnn.com";
NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init] // [NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ([data length] >0 && error == nil && [httpResponse statusCode] == 200)
{
// DO YOUR WORK HERE
// the returned data is usually json format
// use NSJSONSerialization api to parse the data
}
else if ([data length] == 0 && error == nil)
{
NSLog(@"Nothing was downloaded.");
}
else if (error != nil){
NSLog(@"Error = %@", error);
}
}];
2. 用 NSURLSession 访问 URL
例子:假设我们要访问伦敦的天气,先定义一个url:
NSString *londonWeatherUrl =
@"http://api.openweathermap.org/data/2.5/weather?q=London,uk";
我们先用 NSURLConnection 的方式实现:
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:londonWeatherUrl]];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
// handle response
}];
再用 NSURLSession实现:
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
// handle response
}] resume];
注意,我们是用了最简单、最快速的方法使用 NSURLSession。我们甚至没有指定queue,它会自动在后台执行下载任务。
另外,也可以使用AFNetworking来实现:
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:londonWeatherUrl]];
AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request,
NSHTTPURLResponse *response,
id JSON) {
// handle response
} failure:nil];
[operation start];
用 AFNetworking的好处是返回的数据直接是json格式的,省的自己再解析了。
参考文章:
1. apple官方:
2. 著名的 Tutorial 系列: