iOS中——iOS网络通信中的同步请求和异步请求

本文详细介绍了iOS中的网络通信方法,包括同步和异步请求的区别、GET与POST请求的特点及使用场景,同时给出了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

iOS中——iOS网络通信中的同步请求和异步请求


(一)、同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作,

(二)、异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然可以对UI进行操作,程序可以继续运行

(三)、GET请求,将参数直接写在访问路径上。操作简单,不过容易被外界看到,安全性不高,地址最多255字节;

(四)、POST请求,将参数放到body里面。POST请求操作相对复杂,需要将参数和地址分开,不过安全性高,参数放在body里面,不易被捕获。


1 、 同步 GET 请求

//第一步,创建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 ) ;

2 、同步 POST 请求

//第一步,创建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 ) ;

3 、异步 GET 请求

//第一步,创建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 ] ;

4 、异步 POST 请求

//第一步,创建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方法,方法使用如下:

  1. - (void)httpAsynchronousRequest{  
  2.   
  3.     NSURL *url = [NSURL URLWithString:@"http://url"];  
  4.       
  5.     NSString *post=@"postData";  
  6.       
  7.     NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];  
  8.   
  9.     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];  
  10.     [request setHTTPMethod:@"POST"];  
  11.     [request setHTTPBody:postData];  
  12.     [request setTimeoutInterval:10.0];  
  13.       
  14.     NSOperationQueue *queue = [[NSOperationQueue alloc]init];  
  15.     [NSURLConnection sendAsynchronousRequest:request  
  16.                                        queue:queue  
  17.                            completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){  
  18.                                if (error) {  
  19.                                    NSLog(@"Httperror:%@%d", error.localizedDescription,error.code);  
  20.                                }else{  
  21.                                      
  22.                                    NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];  
  23.                                      
  24.                                    NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];  
  25.                                      
  26.                                    NSLog(@"HttpResponseCode:%d", responseCode);  
  27.                                    NSLog(@"HttpResponseBody %@",responseString);  
  28.                                }  
  29.                            }];  
  30.   
  31.       
  32. }  

      sendAsynchronousReques可以很容易地使用NSURLRequest接收回调,完成http通信。

2)connectionWithRequest

iOS2.0就开始支持connectionWithRequest方法,使用如下:


  1. - (void)httpConnectionWithRequest{  
  2.       
  3.     NSString *URLPath = [NSString stringWithFormat:@"http://url"];  
  4.     NSURL *URL = [NSURL URLWithString:URLPath];  
  5.     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];  
  6.     [NSURLConnection connectionWithRequest:request delegate:self];  
  7.       
  8. }  
  9.   
  10. - (void)connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response  
  11. {  
  12.      
  13.     NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];  
  14.     NSLog(@"response length=%lld  statecode%d", [response expectedContentLength],responseCode);  
  15. }  
  16.   
  17.   
  18. // A delegate method called by the NSURLConnection as data arrives.  The  
  19. // response data for a POST is only for useful for debugging purposes,  
  20. // so we just drop it on the floor.  
  21. - (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data  
  22. {  
  23.     if (mData == nil) {  
  24.         mData = [[NSMutableData alloc] initWithData:data];  
  25.     } else {  
  26.         [mData appendData:data];  
  27.     }  
  28.     NSLog(@"response connection");  
  29. }  
  30.   
  31. // A delegate method called by the NSURLConnection if the connection fails.  
  32. // We shut down the connection and display the failure.  Production quality code  
  33. // would either display or log the actual error.  
  34. - (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error  
  35. {  
  36.       
  37.     NSLog(@"response error%@", [error localizedFailureReason]);  
  38. }  
  39.   
  40. // A delegate method called by the NSURLConnection when the connection has been  
  41. // done successfully.  We shut down the connection with a nil status, which  
  42. // causes the image to be displayed.  
  43. - (void)connectionDidFinishLoading:(NSURLConnection *)theConnection  
  44. {  
  45.     NSString *responseString = [[NSString alloc] initWithData:mData encoding:NSUTF8StringEncoding];  
  46.      NSLog(@"response body%@", responseString);  
  47. }  


   connectionWithRequest需要delegate参数,通过一个delegate来做数据的下载以及Request的接受以及连接状态,此处delegate:self,所以需要本类实现一些方法,并且定义mData做数据的接受。

需要实现的方法:


1、获取返回状态、包头信息。

  1. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;  

2、连接失败,包含失败。

  1. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;  


3、接收数据
  1. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;  


4、数据接收完毕

- (void)connectionDidFinishLoading:(NSURLConnection *)connection;


    connectionWithRequest使用起来比较繁琐,而iOS5.0之前用不支持sendAsynchronousRequest。有网友提出了AEURLConnection解决方案。

[html]  view plain copy print ?
  1. 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、同步请求

同步请求数据方法如下:

  1. - (void)httpSynchronousRequest{  
  2.       
  3.     NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];  
  4.     NSURLResponse * response = nil;  
  5.     NSError * error = nil;  
  6.     NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest  
  7.                                           returningResponse:&response  
  8.                                                       error:&error];  
  9.       
  10.     if (error == nil)  
  11.     {  
  12.         // 处理数据  
  13.     }  
  14. }  


同步请求数据会造成主线程阻塞,通常在请求大数据或网络不畅时不建议使用。


        从上面的代码可以看出,不管同步请求还是异步请求,建立通信的步骤基本是一样的:

         1、创建NSURL

         2、创建Request对象

         3、创建NSURLConnection连接。

         NSURLConnection创建成功后,就创建了一个http连接。异步请求和同步请求的区别是:创建了异步请求,用户可以做其他的操作,请求会在另一个线程执行,通信结果及过程会在回调函数中执行。同步请求则不同,需要请求结束用户才能做其他的操作。



参考:
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html#//apple_ref/doc/uid/20001836-BAJEAIEE
http://codewithchris.com/tutorial-how-to-use-ios-nsurlconnection-by-example/
http://kelp.phate.org/2011/06/ios-stringwithcontentsofurlnsurlconnect.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值