你的位置:首页 > 操作系统

[操作系统]NSURLConnection学习笔记


虽说现在都用三方库来获取网络数据,再不济也会用苹果官方的NSURLSession,但有些东西还是要先学会才有资格说不好不用,不是么?

NSURLConnection发送请求是分为同步和异步两种方式的,同步顾名思义就是在发送请求的同时就要立刻处理,在主线程中会阻塞其他操作,如果网络请求比较耗时的话,就会影响用户体验。同步方法如下:

1 + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;

这是一个返回值为NSURLConnection的类方法。为什么同步有返回值异步的没有呢,这个稍后再说。

 

异步请求就不会阻塞主线程的其他操作了,根据服务器返回数据处理方式的不同又可以分为两种:

block回调

1 + (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue                         completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler;

代理

1 - (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;2 3 - (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;

两个对象方法,后一个可以控制是否立即请求,传NO的话可以在之后需要请求的时候调用start方法开始请求。

还有一个类方法:

+ (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;

成为NSURLConnection的代理,需要遵守NSURLConnectionDataDelegate协议,而不是NSURLConnectionDelegate协议。

代理方法如下:

开始接收到服务器的响应时调用- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;接收到服务器返回的数据时调用(服务器返回的数据比较大时会调用多次)- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;服务器返回的数据完全接收完毕后调用- (void)connectionDidFinishLoading:(NSURLConnection *)connection;请求出错时调用(比如请求超时)- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;

 

下面来看一下不同的请求方式

GET:使用GET请求数据,参数要拼接在url中,所以用户信息等比较敏感的内容不要用GET方式。

POST:使用POST请求数据,参数要放在请求体中,上传操作要使用POST方式。

使用POST方式时要使用可变请求NSMutableRequest

设置请求超时等待时间(超过这个时间就算超时,请求失败)- (void)setTimeoutInterval:(NSTimeInterval)seconds;设置请求方法(比如GET和POST)- (void)setHTTPMethod:(NSString *)method;设置请求体- (void)setHTTPBody:(NSData *)data;设置请求头- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

 

最后要注意的是,请求体(也就是参数)中如果有中文时,需要使用utf-8进行编码

// GETNSString *urlStr = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];// POSTrequest.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];

 

至于异步函数为什么没有返回值的问题,原因是异步函数进行网络请求的时间不确定,所以要等到数据返回后才能开始进一步的操作,如果直接使用对象接收返回值的话,可能造成空值,所以使用block或者代理对返回的数据进行操作。