如何使用
NSURLConnection是IOS SDK偏于上层的网络API,NSURLConnection对象通过加载URL请求来实现网络连接。NSURLConnection的接口非常少,只提供了控制启动和取消异步加载的相关方法。
NSURLConnection的委托NSURLConnection准许对象接受一个URL请求的异步回调,并在一个网络请求的生命周期的关键点上都提供了相关的回调函数进行处理,在代码的编写过程中可以只进行逻辑处理,而不必关心与服务器建立连接、发送以及接受请求包等过程。
下面我们以一个NSURLConnection的初始化为例
一、初始化请求
1、创建一个NSURL对象,
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com/img/baidu_sylogo1.gif"];
2、创建一个NSURLRequest对象,主要有两个方法:一个直接用NSURL创建,另一个是指定缓存策略以及超时时间。
直接用NSURL创建,代码如下:
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
指定缓存策略以及超时时间,代码如下:
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
创建完NSURLRequest后就可以创建NSURLConnection了。
二、缓存策略
缓存类型
NSURLRequestUseProtocolCachePolicy 默认的缓存策略,是最能保持一致性的缓存策略
NSURLRequestReloadIgnoringCacheData 忽略缓存直接从原始地址下载
NSURLRequestReturnCacheDataElseLoad 只有在缓存中不在data时才从原始地址下载
NSURLRequestReturnCacheDataDontLoad 准许app确定是否要返回cache数据,如果使用这种协议当本地不存在response的时候,创建NSURLConnextion or NSURLDownload 实例时将会马上返回nil;类似于离线模式,没有建立网络连接
三、创建连接
NSURLConnection还有几个初始化函数,有个初始化函数可以做到创建但是并不马上开始下载,而是通过“start:”开始
当收到initWithRequest消息时,在代理(delegate)收到connectionDidFinishLoading或者didFailWithError消息之前可以通过给连接发送一个cancel消息来中断下载。
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
四、委托描述
//应答前收到
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"didReceiveResponse");
}
当下载开始的时候,每当有数据接受时,代理会定期收到didReceiveData消息。这种情况下、代理应当在实现中存储新接受的数据,
//接受数据回调
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"didReceiveData");
UIImage *image = [[UIImage alloc] initWithData:data];
[[self imageView] setImage:image];
}
在下载的过程中有错误发生的时候,代理会收到一个didFailWithError消息,消息参数里面的NSError对象提供了具体的错误细节,并能通过NSErrorFailingURLStringKey提供在用户信息字典里面失败的url请求。当代理接受到连接的didFailWithError消息后,对于该链接不会再收到任何消息。
//网络连接错误
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"didFailWithError");
}
如果连接请求成功的下载,代理会接受connectionDidFinishLoading消息,且不会收到其他的消息。在消息的实现中,应该释放连接。
//网络连接成功
{
NSLog(@"connectionDidFinishLoading");
}
在非主线程运行NSURLConnection
说明:不推荐在非主线程使用NSURLConnection。
确实想要 在其他线程运行的话,解决方案如下:
The problem arises from the background thread stopping before the NSURLConnection
actually gets any response. Luckily it's pretty easy to force a thread/run loop to keep running with CFRunLoopRun()
. Just don't forget to stop it when you're done with CFRunLoopStop(CFRunLoopGetCurrent())
.
- - (void)startLoadWithURL:(NSURL *)url {
- NSURLRequest *request = [NSURLRequest requestWithURL:url];
- [NSURLConnection connectionWithRequest:request delegate:self];
- CFRunLoopRun();
- }
-
- - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
-
- CFRunLoopStop(CFRunLoopGetCurrent());
- }
-
- - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
-
- CFRunLoopStop(CFRunLoopGetCurrent());
- }
不能在启动NSConnection的线程sleep,只能用CFRunLoopRun,否则也收不到消息。
应该是依赖于执行线程在空闲期的异步接接收网络数据。