iOS网络通信类库用AFNetworking替换ASHttpRequest的解决方案

来源:互联网 发布:诛仙手游有炼器软件吗 编辑:程序博客网 时间:2024/06/05 18:19

http://blog.csdn.net/lgm252008/article/details/40450411

一、AFNetworking替换ASHttpRequest原因
经过近两年开发IOS使用AFNetworking和ASIHttpRequest的经验,结合在实际开发App的遇到网络问题

和线上app用户反馈及在用测试工具开发测试中的反应情况,最后得出结论AFNetworking的优点相对ASIHttpReqeuest的优点大一些,尤其在网络稳定性方面。处理crash这些情况,下面通过两者详细的优缺点比较了解 一下,为什么把ASIHttpRequest给替换成了ASNetworking。

二、AFNetworking的优缺点
优点:
        维护和使用者相对多
        对ARC的支持
        对Block使用的支持非常好
        维护和使用者相对多(目前已到2.4.1版)
       专门对异步请求的支持
       支持基于url缓存的支持
       图片及NSURLCache、AFCache缓存实用
       支持后台下载,缓存离线请求的支持(SDURLCache)
       对JSON支持好
      对实现的http请求比较容易
      对https的支持

缺点:
      是基于Foundation框架的NSURLConnection对网络进行的封装不是用的低层的
CFNetwork进行的封装扩展的功能目前相对少一些,但在Http上的网络支持已足够

ASIHttpRequest:
优点:

        对网络底层CFNetwork支持,在性能上占优
        对代理proxy支持设置比较方便
        支持离线下载和基于url的缓存
        对https的支持
        对实现的http请求方面实现的不是太好,会多写点代码
        支持异步和同步的支持


缺点:
       在2012年社区已停止更新
       对目前最新版本IOS7和8上使用时会有些问题,特别是网络异步请求多时,多线程使用时经常出现时容易出现网络不稳定的问题。
       对ARC支持不好,不支持苹果推荐给我们使用的ARC性能
       对Block不够好,框架代码在多线程方面用的不好
       ASI框架在面向对象方面不够抽象
       接口和实现代码看着过于庞大,里面过程化的实现比较严重不利于扩展和维护

三、在代码实现仅用GET请求来做一下AFNetworking和ASIHttpRequest的比较:


[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * AFNetworking初始化HTTP 
  3.  */  
  4. - (void)httpInit  
  5. {  
  6.     //应用配置文件  
  7.     self.manager = [AFHTTPRequestOperationManager manager];  
  8.       
  9.     //申明返回的结果是JSON类型  
  10.     self.manager.responseSerializer = [AFJSONResponseSerializer serializer];  
  11.       
  12.     //如果报接受类型不一致请替换一致text/html  
  13.     self.manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];  
  14.       
  15.     //清求时间设置  
  16.     self.manager.requestSerializer.timeoutInterval = 30;  
  17.       
  18.     //设置代理  
  19.     //[self setProxy];  
  20.       
  21.     //添加header头信息  
  22.     [self addRequestHeader];  
  23. }  
  24.   
  25. /** 
  26.  * AFNetworking发送get请求 
  27.  */  
  28. - (void)startGet:(NSString*)uri tag:(NSInteger)tag  
  29. {  
  30.     [self httpInit];  
  31.       
  32.     [self.manager GET:[NSString stringWithFormat:@"%@%@",self.baseUrl,uri] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {  
  33.           
  34.         [self requestFinished:responseObject tag:tag];  
  35.     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  36.   
  37.         [self requestFailed:tag];  
  38.     }];  
  39. }  
  40.   
  41.   
  42. /** 
  43.  * ASIHttpRequest初始化HTTP 
  44.  */  
  45. -(void)httpInit:(NSString *)method uri:(NSString *)uri  
  46. {  
  47.     //应用配置文件  
  48.     [self setRes:[ASIFormDataRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",self.baseUrl,uri]]]];  
  49.   
  50.     //设置代理  
  51.     if (self.host != nil) {  
  52.         [self.res setProxyHost:self.host];  
  53.     }  
  54.       
  55.     if (self.port > 0) {  
  56.         [self.res setProxyPort:self.port];  
  57.     }  
  58.     //设置代理  
  59.     [self.res setDelegate:self];  
  60.       
  61.     //设置允许记录cookie  
  62.     [self.res setUseCookiePersistence:YES];  
  63.       
  64.     //超时设置  
  65.     [self.res setTimeOutSeconds:30];  
  66.       
  67.     //请求方式  
  68.     [self.res setRequestMethod:method];  
  69. }  
  70.   
  71. /** 
  72.  * ASIHttpRequest发送get请求 
  73.  */  
  74. - (void)startGet:(NSString*)uri tag:(NSInteger)tag{  
  75.   
  76.     [self cancel];//取消前一个请求  
  77.     [self httpInit:@"GET" uri:uri];  
  78.     [self.res setTag:tag];  
  79.     [self.res startAsynchronous];  
  80. }  

四、AFNetworking在Model层对app的网络请求的封装实现过的代码:
initData.h

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //  
  2. //  InitData.h  
  3. //  
  4. //  Created by ligangming on 14-1-2.  
  5. //  Copyright (c) 2014年 ligangming. All rights reserved.  
  6. //  
  7.   
  8. #define DEFAULT_PAGESIZE 20 //默认分页数量  
  9.   
  10. /** 
  11.  请求完成处理 
  12. */  
  13. typedef void (^Complete)();  
  14.   
  15. /** 
  16.  请求失败处理 
  17. */  
  18. typedef void (^Failed)(NSString *state,NSString *errmsg);  
  19.   
  20. /** 
  21. 数据请求模型的基类,包含基本网络请求 
  22. */  
  23. @interface InitData : NSObject{  
  24.   
  25. @protected  
  26.   
  27.     Complete _complete; //请求完成  
  28.     Failed   _failed;   //请求失败  
  29. }  
  30.   
  31. //HTTP参数设置  
  32. @property(nonatomic,strong)NSString         *baseUrl;       //API基础地址  
  33. @property(nonatomic,strong)NSString         *host;          //代理主机IP地址  
  34. @property(nonatomic,assign)NSInteger        port;           //代理主机端口  
  35.   
  36. @property(nonatomic,strong)NSString         *errCode;       //错误代码  
  37. @property(nonatomic,strong)NSString         *errMsg;        //错误描述  
  38. @property(nonatomic,strong)NSString         *version;       //协议版本(客户端兼容最小版本)  
  39.   
  40. - (id)initWithDelegate:(id)delegate;  
  41. /** 
  42.  * 发送get请求 
  43.  */  
  44. - (void)startGet:(NSString*)url tag:(NSInteger)tag;  
  45.   
  46. /** 
  47.  * 发送getCache请求 
  48.  */  
  49. - (void)startCache:(NSString *)aCacheName cacheTime:(NSInteger)aTime uri:(NSString *)uri tag:(NSInteger)tag;  
  50.   
  51. /** 
  52.  * 发送post请求 
  53.  */  
  54. - (void)startPost:(NSString*)url params:(NSDictionary*)params tag:(NSInteger)tag;  
  55.   
  56. /** 
  57.  * 上传文件 
  58.  */  
  59. - (void)uploadFileURI:(NSString*)aUri filePath:(NSString*)aPath keyName:(NSString *)aKeyName;  
  60.   
  61. /** 
  62.  * 取消请求 
  63.  */  
  64. - (void)cancel;  
  65. @end  
  66.   
  67. #pragma mark delegate  
  68. @protocol InitDataDelegate <NSObject>  
  69. @optional  
  70. /** 
  71.  请求完成时-调用 
  72.  */  
  73. -(void)getFinished:(NSDictionary *)msg tag:(NSInteger)tag;  
  74.   
  75. /** 
  76.  请求失败时-调用 
  77.  */  
  78. -(void)getError:(NSDictionary *)msg tag:(NSInteger)tag;  
  79.   
  80. @end  

initData.m

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //  
  2. //  InitData.m  
  3. //  
  4. //  Created by ligangming on 14-1-2.  
  5. //  Copyright (c) 2014年 ligangming. All rights reserved.  
  6. //  
  7.   
  8. #import "InitData.h"  
  9. #import "AFNetworking.h"  
  10.   
  11. Class object_getClass(id object);  
  12.   
  13. @interface InitData()  
  14. {  
  15.     Class afOrinClass;  
  16. }  
  17.   
  18. @property(nonatomic,strong)AFHTTPRequestOperationManager *manager; //AF请求对象  
  19. @property(nonatomic,weak)id<InitDataDelegate> delegate;  
  20. @end  
  21.   
  22. @implementation InitData  
  23.   
  24. #pragma mark initData  
  25. - (id)initWithDelegate:(id)delegate  
  26. {  
  27.     if ((self = [super init])) {  
  28.         afOrinClass = object_getClass(delegate);  
  29.         [self setDelegate:delegate];  
  30.         [self setDefault];  
  31.     }  
  32.       
  33.     return self;  
  34. }  
  35.   
  36. /** 
  37.  * 初始化设置 
  38.  */  
  39. - (void)setDefault  
  40. {  
  41.     //载入系统配置  
  42.     NSDictionary *cfgDic = [NSObject JzbGetConfig];  
  43.       
  44.     //API地址  
  45.     [self setBaseUrl:[cfgDic objectForKey:@"apiUrl"]];  
  46.       
  47.     //代理HOST  
  48.     if (![[cfgDic objectForKey:@"apiHost"] isEqualToString:@""]) {  
  49.           
  50.         [self setHost:[cfgDic objectForKey:@"apiHost"]];  
  51.           
  52.         //重置API地址(测试用)  
  53.         [self setBaseUrl:[NSString stringWithFormat:@"http://%@"self.host]];  
  54.     }else{  
  55.         [self setHost:nil];  
  56.     }  
  57.    
  58.     //代理port  
  59.     [self setPort:[[cfgDic objectForKey:@"apiPort"] intValue]];  
  60. }  
  61.   
  62. #pragma mark httpMode  
  63. /** 
  64.  * 初始化HTTP 
  65.  */  
  66. - (void)httpInit  
  67. {  
  68.     //应用配置文件  
  69.     self.manager = [AFHTTPRequestOperationManager manager];  
  70.       
  71.     //申明返回的结果是JSON类型  
  72.     self.manager.responseSerializer = [AFJSONResponseSerializer serializer];  
  73.       
  74.     //如果报接受类型不一致请替换一致text/html  
  75.     self.manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];  
  76.       
  77.     //清求时间设置  
  78.     self.manager.requestSerializer.timeoutInterval = 30;  
  79.       
  80.     //设置代理  
  81.     //[self setProxy];  
  82.       
  83.     //添加header头信息  
  84.     [self addRequestHeader];  
  85. }  
  86.   
  87. /** 
  88.  * 添加header头信息 
  89.  */  
  90. - (void)addRequestHeader  
  91. {  
  92.     //当前应用版块号  
  93.       
  94.     //应用类型IOS  
  95.       
  96.     //当前应用  
  97.     [self.manager.requestSerializer setValue:@"xxx" forHTTPHeaderField:@"TOKEN"];  
  98. }  
  99.   
  100. /** 
  101.  * 发送get请求 
  102.  */  
  103. - (void)startGet:(NSString*)uri tag:(NSInteger)tag  
  104. {  
  105.     [self httpInit];  
  106.       
  107.     [self.manager GET:[NSString stringWithFormat:@"%@%@",self.baseUrl,uri] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {  
  108.           
  109.         [self requestFinished:responseObject tag:tag];  
  110.     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  111.   
  112.         [self requestFailed:tag];  
  113.     }];  
  114. }  
  115.   
  116. - (AFHTTPRequestOperation *)cacheOperationWithRequest:(NSURLRequest *)urlRequest  
  117.                                                   tag:(NSInteger)tag  
  118.                                               success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success  
  119.                                               failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure  
  120. {      
  121.     AFHTTPRequestOperation *operation = [self.manager HTTPRequestOperationWithRequest:urlRequest success:^(AFHTTPRequestOperation *operation, id responseObject){  
  122.           
  123.         NSCachedURLResponse *cachedURLResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:urlRequest];  
  124.         cachedURLResponse = [[NSCachedURLResponse alloc] initWithResponse:operation.response data:operation.responseData userInfo:nil storagePolicy:NSURLCacheStorageAllowed];  
  125.         [[NSURLCache sharedURLCache] storeCachedResponse:cachedURLResponse forRequest:urlRequest];  
  126.           
  127.         success(operation,responseObject);  
  128.     }failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  129.           
  130.         if (error.code == kCFURLErrorNotConnectedToInternet) {  
  131.             NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:urlRequest];  
  132.             if (cachedResponse != nil && [[cachedResponse data] length] > 0) {  
  133.                 success(operation, cachedResponse.data);  
  134.             } else {  
  135.                 failure(operation, error);  
  136.             }  
  137.         } else {  
  138.             failure(operation, error);  
  139.         }  
  140.     }];  
  141.       
  142.     return operation;  
  143. }  
  144.   
  145. /** 
  146.  * 发送getCache请求 
  147.  */  
  148. - (void)startCache:(NSString *)aCacheName cacheTime:(NSInteger)aTime uri:(NSString *)uri tag:(NSInteger)tag  
  149. {  
  150.     [self httpInit];  
  151.       
  152.     AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];  
  153.     NSMutableURLRequest *request = [serializer requestWithMethod:@"GET" URLString:[NSString stringWithFormat:@"%@%@",self.baseUrl,uri] parameters:nil error:nil];  
  154.       
  155.     [request setTimeoutInterval:20];  
  156.     [request setCachePolicy:NSURLRequestUseProtocolCachePolicy]; //此处将NSURLRequestReturnCacheDataElseLoad替换要不然无论有无网络情况每次请求都会取本地缓存数据  
  157.       
  158.     //请求成功Block块  
  159.     void (^requestSuccessBlock)(AFHTTPRequestOperation *operation, id responseObject) = ^(AFHTTPRequestOperation *operation, id responseObject) {  
  160.           
  161.         [self requestFinished:responseObject tag:tag];  
  162.     };  
  163.       
  164.     //请求失败Block块  
  165.     void (^requestFailureBlock)(AFHTTPRequestOperation *operation, NSError *error) = ^(AFHTTPRequestOperation *operation, NSError *error){  
  166.           
  167.         [self requestFailed:tag];  
  168.     };  
  169.       
  170.     //请求数据  
  171.     AFHTTPRequestOperation *operation = [self cacheOperationWithRequest:request tag:tag success:requestSuccessBlock failure:requestFailureBlock];  
  172.     [self.manager.operationQueue addOperation:operation];  
  173. }  
  174.   
  175. /**  
  176.  * 获取缓存数据 
  177.  */  
  178. - (id)cachedResponseObject:(AFHTTPRequestOperation *)operation{  
  179.       
  180.     NSCachedURLResponse* cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:operation.request];  
  181.     AFHTTPResponseSerializer* serializer = [AFJSONResponseSerializer serializer];  
  182.     id responseObject = [serializer responseObjectForResponse:cachedResponse.response data:cachedResponse.data error:nil];  
  183.     return responseObject;  
  184. }  
  185.   
  186. /** 
  187.  * 发送post请求 
  188.  */  
  189. - (void)startPost:(NSString*)uri params:(NSDictionary*)params tag:(NSInteger)tag  
  190. {  
  191.     [self httpInit];  
  192.       
  193.     [self.manager POST:[NSString stringWithFormat:@"%@%@",self.baseUrl,uri] parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {  
  194.           
  195.         [self requestFinished:responseObject tag:tag];  
  196.     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  197.       
  198.         [self requestFailed:tag];  
  199.     }];  
  200. }  
  201.   
  202. /** 
  203.  * 上传文件 
  204.  */  
  205. - (void)uploadFileURI:(NSString *)aUri filePath:(NSString *)aPath keyName:(NSString *)aKeyName  
  206. {  
  207.     [self httpInit];  
  208.       
  209.     [self.manager POST:[NSString stringWithFormat:@"%@%@",self.baseUrl,aUri]  parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {  
  210.           
  211.         NSData *imageData = [[NSData alloc] initWithContentsOfFile:aPath];  
  212.           
  213.         //获取文件类型  
  214.         NSMutableString *filePath = [NSMutableString stringWithString:aPath];  
  215.         CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[filePath pathExtension], NULL);  
  216.         CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);  
  217.           
  218.         NSString *fileName = [filePath lastPathComponent];  
  219.           
  220.         //将得到的二进制图片拼接到表单中 /** data,指定上传的二进制流;name,服务器端所需参数名;fileName,指定文件名;mimeType,指定文件格式 */  
  221.         [formData appendPartWithFileData:imageData name:aKeyName fileName:fileName mimeType:(__bridge NSString *)(MIMEType)];  
  222.           
  223.     }success:^(AFHTTPRequestOperation *operation, id responseObject){  
  224.           
  225.         [self requestFinished:responseObject tag:200];  
  226.           
  227.     }failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  228.           
  229.     }];      
  230.       
  231.     /* 
  232.      /设置上传操作的进度 
  233.       
  234.      [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { 
  235.       
  236.         NSLog(@"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite); 
  237.      }]; 
  238.       
  239.      UIProgressView *progress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; 
  240.       
  241.      [progress setProgressWithUploadProgressOfOperation:operation animated:YES]; 
  242.       
  243.      [progress setFrame:CGRectMake(0, 130, 320, 30)]; 
  244.       
  245.      [self.view addSubview:progress]; 
  246.     */  
  247.     //[operation start];  
  248. }  
  249.   
  250. /** 
  251.  停止请求 
  252.  */  
  253. - (void)cancel  
  254. {  
  255.     if (_manager != nil) {  
  256.         _manager = nil;  
  257.     }  
  258. }  
  259.   
  260. /** 
  261.  * 清理回调block 
  262.  */  
  263. - (void)cleanupBlocks  
  264. {  
  265.     _complete = nil;  
  266.     _failed = nil;  
  267. }  
  268.   
  269. /* 
  270. 解析通用协议头: 
  271. 1.检查协议体合法性 
  272. 2.协议版本检查,执行协议版本客户端处理逻辑 
  273.  
  274. 返回值:BOOL 通过解析检查返回YES,否则 NO 
  275. 对于没有通过检查的协议消息,返回客户端协议错误的消息,或者版本不支持的错误 
  276. */  
  277. - (BOOL)parseHead:(NSDictionary*)msg  
  278. {  
  279.     //错误代码解析  
  280.     //错误描述  
  281.     //版本提取,客户端版本规则逻辑执行  
  282.       
  283.     return YES;  
  284. }  
  285.   
  286. #pragma mark AFHTTPDelegate  
  287. /** 
  288.  * 代理-请求结束 
  289.  */  
  290. - (void)requestFinished:(NSDictionary *)aDictionary tag:(NSInteger)aTag  
  291. {  
  292.     //如果消息头解析成功并通过合法性检查  
  293.     if([self parseHead:aDictionary] == YES){  
  294.   
  295.         if ([self.errCode intValue] <= 0) {  
  296.               
  297.             if ([self.delegate respondsToSelector:@selector(getFinished:tag:)]) {  
  298.                 [self.delegate getFinished:aDictionary tag:aTag];  
  299.             }  
  300.         }else{  
  301.             if (_failed) {  
  302.                 _failed(self.errCode,self.errMsg);  
  303.             }  
  304.             if ([self.delegate respondsToSelector:@selector(getError:tag:)]) {  
  305.                 [self.delegate getError:aDictionary tag:aTag];  
  306.             }  
  307.         }  
  308.     }  
  309. }  
  310.   
  311. /** 
  312.  * 代理-请求失败 
  313.  */  
  314. - (void)requestFailed:(NSInteger)aTag  
  315. {  
  316.     if (afOrinClass != object_getClass(_delegate)) {  
  317.         NSLog(@"model已销毁");  
  318.         return;  
  319.     }  
  320.       
  321.     if (_failed) {  
  322.         _failed(@"1",@"request error");  
  323.     }  
  324.       
  325.     //检测如果有配置代理则去执行代理  
  326.     if ([self.delegate respondsToSelector:@selector(getError:tag:)]) {  
  327.         NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"1",@"errcode",@"request error",@"errmsg", nil nil];  
  328.         [self.delegate getError:dic tag:aTag];  
  329.     }  
  330. }  
  331.   
  332. @end  
0 0
原创粉丝点击