iOS中——iOS网络通信中的同步请求和异步请求
(一)、同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作,
(二)、异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然可以对UI进行操作,程序可以继续运行
(三)、GET请求,将参数直接写在访问路径上。操作简单,不过容易被外界看到,安全性不高,地址最多255字节;
(四)、POST请求,将参数放到body里面。POST请求操作相对复杂,需要将参数和地址分开,不过安全性高,参数放在body里面,不易被捕获。
//第一步,创建URL
NSURL * url = [ NSURL URLWithString : @ "http://api.hudong.com/iphonexml.do?type=focus-c" ] ;
//第二步,通过URL创建网络请求
NSURLRequest * request = [ [ NSURLRequest alloc ] initWithURL : url
cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval : 10 ] ;
//NSURLRequest初始化方法第一个参数:请求访问路径,第二个参数:缓存协议,
第三个参数:网络请求超时时间(秒)
其中缓存协议是个枚举类型包含:
NSURLRequestUseProtocolCachePolicy (基础策略)
NSURLRequestReloadIgnoringLocalCacheData (忽略本地缓存)
NSURLRequestReturnCacheDataElseLoad (首先使用缓存,如果没有本地缓存,才从原地址下载)
NSURLRequestReturnCacheDataDontLoad
(使用本地缓存,从不下载,如果本地没有缓存,则请求失败,此策略多用于离线操作)
NSURLRequestReloadIgnoringLocalAndRemoteCacheData
(无视任何缓存策略,无论是本地的还是远程的,总是从原地址重新下载)
NSURLRequestReloadRevalidatingCacheData
(如果本地缓存是有效的则不下载,其他任何情况都从原地址重新下载)
//第三步,连接服务器
NSURLResponse *response;
NSData * received = [ NSURLConnection sendSynchronousRequest : request
returningResponse : &response error : nil ] ;
NSString * str = [ [ NSString alloc ] initWithData : received encoding :NSUTF8StringEncoding ] ;
NSLog ( @ "%@" , str ) ;
//第一步,创建URL
NSURL * url = [ NSURL URLWithString : @ "http://api.hudong.com/iphonexml.do" ] ;
//第二步,创建请求
NSMutableURLRequest * request = [ [ NSMutableURLRequest alloc ] initWithURL : url
cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval : 10 ] ;
[ request setHTTPMethod : @ "POST" ] ; //设置请求方式为POST,默认为GET
NSString * str = @ "type=focus-c" ; //设置参数
NSData * data = [ str dataUsingEncoding : NSUTF8StringEncoding ] ;
[ request setHTTPBody : data ] ;
//第三步,连接服务器
NSURLResponse *response;
NSData * received = [ NSURLConnection sendSynchronousRequest : request
returningResponse &response : nil error : nil ] ;
NSString * str1 = [ [ NSString alloc ] initWithData : received encoding :NSUTF8StringEncoding ] ;
NSLog ( @ "%@" , str1 ) ;
//第一步,创建url
NSURL * url = [ NSURL URLWithString : @ "http://api.hudong.com/iphonexml.do?type=focus-c" ] ;
//第二步,创建请求
NSURLRequest * request = [ [ NSURLRequest alloc ] initWithURL : url
cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval : 10 ] ;
//第三步,连接服务器
NSURLConnection * connection = [ [ NSURLConnection alloc ] initWithRequest : request
delegate : self ] ;
//第一步,创建url
NSURL * url = [ NSURL URLWithString : @ "http://api.hudong.com/iphonexml.do" ] ;
//第二步,创建请求
NSMutableURLRequest * request = [ [ NSMutableURLRequest alloc ] initWithURL : url
cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval : 10 ] ;
[ request setHTTPMethod : @ "POST" ] ;
NSString * str = @ "type=focus-c" ;
NSData * data = [ str dataUsingEncoding : NSUTF8StringEncoding ] ;
[ request setHTTPBody : data ] ;
//第三步,连接服务器
NSURLConnection * connection = [ [ NSURLConnection alloc ] initWithRequest : request
delegate : self ] ;
5 、异步请求的代理方法
//接收到服务器回应的时候调用此方法
- ( void ) connection : ( NSURLConnection * ) connection
didReceiveResponse : ( NSURLResponse * ) response
NSHTTPURLResponse * res = ( NSHTTPURLResponse * ) response ;
NSLog ( @ "%@" , [ res allHeaderFields ] ) ;
self . receiveData = [ NSMutableData data ] ;
//接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次
- ( void ) connection : ( NSURLConnection * ) connection didReceiveData : ( NSData * )data
[ self . receiveData appendData : data ] ;
//数据传完之后调用此方法
- ( void ) connectionDidFinishLoading : ( NSURLConnection * ) connection
NSString * receiveStr = [ [ NSString alloc ] initWithData : self . receiveData
encoding : NSUTF8StringEncoding ] ;
NSLog ( @ "%@" , receiveStr ) ;
//网络请求过程中,出现任何错误(断网,连接超时等)会进入此方法
- ( void ) connection : ( NSURLConnection * ) connection
didFailWithError : ( NSError * ) error
NSLog ( @ "%@" , [ error localizedDescription ] ) ;
}
NSURLConnection提供了异步请求、同步请求两种通信方式。
1、异步请求
iOS5.0 SDK NSURLConnection类新增的sendAsynchronousRequest:queue:completionHandler:方法,从而使iOS5支持两种异步请求方式。我们先从新增类开始。
1)sendAsynchronousRequest
iOS5.0开始支持sendAsynchronousReques方法,方法使用如下:
- - (void)httpAsynchronousRequest{
- NSURL *url = [NSURL URLWithString:@"http://url"];
- NSString *post=@"postData";
- NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
- [request setHTTPMethod:@"POST"];
- [request setHTTPBody:postData];
- [request setTimeoutInterval:10.0];
- NSOperationQueue *queue = [[NSOperationQueue alloc]init];
- [NSURLConnection sendAsynchronousRequest:request
- queue:queue
- completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
- if (error) {
- NSLog(@"Httperror:%@%d", error.localizedDescription,error.code);
- }else{
- NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
- NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
- NSLog(@"HttpResponseCode:%d", responseCode);
- NSLog(@"HttpResponseBody %@",responseString);
- }
- }];
- }
sendAsynchronousReques可以很容易地使用NSURLRequest接收回调,完成http通信。
2)connectionWithRequest
iOS2.0就开始支持connectionWithRequest方法,使用如下:
- - (void)httpConnectionWithRequest{
- NSString *URLPath = [NSString stringWithFormat:@"http://url"];
- NSURL *URL = [NSURL URLWithString:URLPath];
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
- [NSURLConnection connectionWithRequest:request delegate:self];
- }
- - (void)connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response
- {
- NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
- NSLog(@"response length=%lld statecode%d", [response expectedContentLength],responseCode);
- }
- // A delegate method called by the NSURLConnection as data arrives. The
- // response data for a POST is only for useful for debugging purposes,
- // so we just drop it on the floor.
- - (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
- {
- if (mData == nil) {
- mData = [[NSMutableData alloc] initWithData:data];
- } else {
- [mData appendData:data];
- }
- NSLog(@"response connection");
- }
- // A delegate method called by the NSURLConnection if the connection fails.
- // We shut down the connection and display the failure. Production quality code
- // would either display or log the actual error.
- - (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error
- {
- NSLog(@"response error%@", [error localizedFailureReason]);
- }
- // A delegate method called by the NSURLConnection when the connection has been
- // done successfully. We shut down the connection with a nil status, which
- // causes the image to be displayed.
- - (void)connectionDidFinishLoading:(NSURLConnection *)theConnection
- {
- NSString *responseString = [[NSString alloc] initWithData:mData encoding:NSUTF8StringEncoding];
- NSLog(@"response body%@", responseString);
- }
connectionWithRequest需要delegate参数,通过一个delegate来做数据的下载以及Request的接受以及连接状态,此处delegate:self,所以需要本类实现一些方法,并且定义mData做数据的接受。
需要实现的方法:
1、获取返回状态、包头信息。
- - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
2、连接失败,包含失败。
- - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
connectionWithRequest使用起来比较繁琐,而iOS5.0之前用不支持sendAsynchronousRequest。有网友提出了AEURLConnection解决方案。
- AEURLConnection is a simple reimplementation of the API for use on iOS 4. Used properly, it is also guaranteed to be safe against The Deallocation Problem, a thorny threading issue that affects most other networking libraries.
2、同步请求
同步请求数据方法如下:
- - (void)httpSynchronousRequest{
- NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
- NSURLResponse * response = nil;
- NSError * error = nil;
- NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
- returningResponse:&response
- error:&error];
- if (error == nil)
- {
- // 处理数据
- }
- }
同步请求数据会造成主线程阻塞,通常在请求大数据或网络不畅时不建议使用。
从上面的代码可以看出,不管同步请求还是异步请求,建立通信的步骤基本是一样的:
1、创建NSURL
2、创建Request对象
3、创建NSURLConnection连接。
NSURLConnection创建成功后,就创建了一个http连接。异步请求和同步请求的区别是:创建了异步请求,用户可以做其他的操作,请求会在另一个线程执行,通信结果及过程会在回调函数中执行。同步请求则不同,需要请求结束用户才能做其他的操作。