虽说现在都用三方库来获取网络数据,再不济也会用苹果官方的NSURLSession,但有些东西还是要先学会才有资格说不好不用,不是么?
NSURLConnection发送请求是分为同步和异步两种方式的,同步顾名思义就是在发送请求的同时就要立刻处理,在主线程中会阻塞其他操作,如果网络请求比较耗时的话,就会影响用户体验。同步方法如下:
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
这是一个返回值为NSURLConnection的类方法。为什么同步有返回值异步的没有呢,这个稍后再说。
异步请求就不会阻塞主线程的其他操作了,根据服务器返回数据处理方式的不同又可以分为两种:
block回调
+ (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler;
代理
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate; - (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进行编码
// GET
NSString *urlStr = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; // POST
request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
至于异步函数为什么没有返回值的问题,原因是异步函数进行网络请求的时间不确定,所以要等到数据返回后才能开始进一步的操作,如果直接使用对象接收返回值的话,可能造成空值,所以使用block或者代理对返回的数据进行操作。