ASIHTTPRequest足够了吗?

来源:互联网 发布:无烟艾灸仪 知乎 编辑:程序博客网 时间:2024/04/27 20:52
ASIHTTPRequest足够了吗?


 大家都知道ASIHTTPRequest系列的类很好用,功能很强大。但也像NSURLConnection一样,一个网络请求就需要实例化一个对象,而且无法避免重复请求的问题。
        我个人不习惯用ASIHTTPRequest,因为它功能太强大了,函数太多了,而我们平时的项目仅仅是处理基于HTTP协议的网络交互,用ASIHTTPRequest未免太“奢侈”了。更重要的是,它并无法避免网络的重复请求的问题,而且无法控制网络请求数量,所以仅仅使用ASIHTTPRequest还不够。
        事实上,用NSURLConnection足够了。下面是我写的封装
HTTPConnection.h
 1. <span style="font-size:16px;">// 
2. //  HTTPConnection.h 
3. //   
4. // 
5. //  Created by Jianhong Yang on 12-1-3. 
6. //  Copyright (c) 2012年 __MyCompanyName__. All rights reserved. 
7. // 
8.  
9. #import <Foundation/Foundation.h> 
10.  
11.  
12. #define  MAXNUMBER_HTTPCONNECTION           30 
13.  
14. @protocol HTTPConnectionDelegate; 
15.  
16. @interface HTTPConnection : NSObject { 
17. @private 
18.     // 
19.     int _numberOfHTTPConnection; 
20.     NSMutableArray *_marrayTaskDic; 
21.      
22.     id <HTTPConnectionDelegate> _delegate; 
23. } 
24.  
25. @property (nonatomic, assign) id <HTTPConnectionDelegate> delegate; 
26.  
27. // 根据URL获取Web数据 
28. // dicParam 
29. //    type:int,请求类型 
30. - (BOOL)requestWebDataWithURL:(NSString *)strURL andParam:(NSDictionary *)dicParam; 
31.  
32. // 根据URLRequest获取Web数据 
33. // dicParam 
34. //    type:int,请求类型 
35. - (BOOL)requestWebDataWithRequest:(NSURLRequest *)request andParam:(NSDictionary *)dicParam; 
36.  
37. //取消网络请求 
38. - (BOOL)cancelRequest:(NSDictionary *)dicParam; 
39.  
40. //清空网络请求 
41. - (void)clearRequest; 
42.  
43. @end 
44.  
45.  
46. @protocol HTTPConnectionDelegate <NSObject> 
47.  
48. @optional 
49.  
50. // 网络数据下载失败 
51. - (void)httpConnect:(HTTPConnection *)httpConnect error:(NSError *)error with:(NSDictionary *)dicParam; 
52.  
53. // 服务器返回的HTTP信息头 
54. - (void)httpConnect:(HTTPConnection *)httpConnect receiveResponseWithStatusCode:(NSInteger)statusCode  
55.  andAllHeaderFields:(NSDictionary *)dicAllHeaderFields with:(NSDictionary *)dicParam; 
56.  
57. // 服务器返回的部分数据 
58. - (void)httpConnect:(HTTPConnection *)httpConnect receiveData:(NSData *)data with:(NSDictionary *)dicParam; 
59.  
60. // 网络数据下载完成 
61. - (void)httpConnect:(HTTPConnection *)httpConnect finish:(NSData *)data with:(NSDictionary *)dicParam; 
62.  
63. @end 
64.  
65.  
66. #ifdef DEBUG 
67.  
68. #define HTTPLOG(fmt,...)     NSLog((@"HTTP->%s(%d):"fmt),__PRETTY_FUNCTION__,__LINE__,##__VA_ARGS__) 
69.  
70. #else 
71.  
72. #define HTTPLOG(fmt,...)     NSLog(fmt,##__VA_ARGS__) 
73.  
74. #endif</span> 

HTTPConnection.m
[plain] view plaincopy
1. // 
2. //  HTTPConnection.m 
3. //   
4. // 
5. //  Created by Jianhong Yang on 12-1-3. 
6. //  Copyright (c) 2012年 __MyCompanyName__. All rights reserved. 
7. // 
8.  
9. #import "HTTPConnection.h" 
10.  
11.  
12. @interface HTTPConnection (Private) 
13. - (void)startHTTPConnection; 
14. @end 
15.  
16.  
17. @implementation HTTPConnection 
18.  
19. @synthesize delegate = _delegate; 
20.  
21. - (id)init 
22. { 
23.     self = [super init]; 
24.     if (self) { 
25.         // Custom initialization. 
26.         _numberOfHTTPConnection = 0; 
27.         _marrayTaskDic = [[NSMutableArray alloc] initWithCapacity:5]; 
28.     } 
29.     return self; 
30. } 
31.  
32. - (void)dealloc 
33. { 
34.     //清空任务 
35.     [self clearRequest]; 
36.     // 
37.     [_marrayTaskDic release]; 
38.      
39.     [super dealloc]; 
40. } 
41.  
42.  
43. #pragma mark - 
44. #pragma mark Public 
45.  
46. // 根据URL获取Web数据 
47. // dicParam 
48. //    type:int,请求类型 
49. - (BOOL)requestWebDataWithURL:(NSString *)strURL andParam:(NSDictionary *)dicParam 
50. { 
51.     if (nil == dicParam) { 
52.         return NO; 
53.     } 
54.      
55.     NSURL *url = [NSURL URLWithString:strURL]; 
56.     NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; 
57.     BOOL success = [self requestWebDataWithRequest:request andParam:dicParam]; 
58.     [request release]; 
59.     return success; 
60. } 
61.  
62. // 根据URLRequest获取Web数据 
63. // dicParam 
64. //    type:int,请求类型 
65. - (BOOL)requestWebDataWithRequest:(NSURLRequest *)request andParam:(NSDictionary *)dicParam 
66. { 
67.     if (nil == dicParam) { 
68.         return NO; 
69.     } 
70.     //请求类型必须存在 
71.     if (nil == [dicParam objectForKey:@"type"]) { 
72.         HTTPLOG(@"任务参数不足"); 
73.         return NO; 
74.     } 
75.     //正在处理或等待处理的任务不再接收 
76.     for (NSDictionary *dicTask in _marrayTaskDic) { 
77.         // 
78.         if ([dicParam isEqualToDictionary:[dicTask objectForKey:@"param"]]) { 
79.             HTTPLOG(@"任务重复:%@", dicParam); 
80.             return NO; 
81.         } 
82.     } 
83.      
84.     HTTPLOG(@"添加新任务,参数:%@", dicParam); 
85.     NSMutableDictionary *mdicTask = [[NSMutableDictionary alloc] initWithCapacity:3]; 
86.     //设置数据缓存 
87.     NSMutableData *mdataCache = [[NSMutableData alloc] init]; 
88.     [mdicTask setObject:mdataCache forKey:@"cache"]; 
89.     [mdataCache release]; 
90.     //参数 
91.     [mdicTask setObject:dicParam forKey:@"param"]; 
92.     //创建HTTP网络连接 
93.     NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 
94.     [mdicTask setObject:urlConnection forKey:@"connect"]; 
95.     [urlConnection release]; 
96.     //保存到数组 
97.     [_marrayTaskDic addObject:mdicTask]; 
98.     [mdicTask release]; 
99.      
100.     [self startHTTPConnection]; 
101.     return YES; 
102. } 
103.  
104. //取消网络请求 
105. - (BOOL)cancelRequest:(NSDictionary *)dicParam 
106. { 
107.     if (nil == dicParam) { 
108.         return NO; 
109.     } 
110.     //遍历所有任务 
111.     for (int i = 0; i < _marrayTaskDic.count; i++) { 
112.         //查看任务是否相同 
113.         NSDictionary *dicTask = [_marrayTaskDic objectAtIndex:i]; 
114.         if ([dicParam isEqualToDictionary:[dicTask objectForKey:@"param"]]) { 
115.             //取消网络请求 
116.             NSURLConnection *connect = [dicTask objectForKey:@"connect"]; 
117.             [connect cancel]; 
118.             //从任务队列中删除 
119.             [_marrayTaskDic removeObjectAtIndex:i]; 
120.             _numberOfHTTPConnection -= 1; 
121.             return YES; 
122.         } 
123.     } 
124.     return NO; 
125. } 
126.  
127. //清空网络请求 
128. - (void)clearRequest 
129. { 
130.     //遍历所有任务 
131.     for (NSDictionary *dicTask in _marrayTaskDic) { 
132.         NSURLConnection *connect = [dicTask objectForKey:@"connect"]; 
133.         [connect cancel]; 
134.         // 
135.         _numberOfHTTPConnection -= 1; 
136.     } 
137.     //从任务队列中删除 
138.     [_marrayTaskDic removeAllObjects]; 
139. } 
140.  
141.  
142. #pragma mark - 
143. #pragma mark NSURLConnectionDataDelegate 
144.  
145. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
146. { 
147.     HTTPLOG(@"网络请求错误:%@", error); 
148.     // 
149.     NSDictionary *dicTask = nil; 
150.     for (int i = 0; i < _marrayTaskDic.count; i++) { 
151.         NSDictionary *dic = [_marrayTaskDic objectAtIndex:i]; 
152.         //找到网络连接相应的数据字典 
153.         if ([dic objectForKey:@"connect"] == connection) { 
154.             dicTask = dic; 
155.             break; 
156.         } 
157.     } 
158.      
159.     // 
160.     if (dicTask) { 
161.         [dicTask retain]; 
162.         //删除 
163.         [_marrayTaskDic removeObject:dicTask]; 
164.         NSDictionary *dicParam = [dicTask objectForKey:@"param"]; 
165.         if ([_delegate respondsToSelector:@selector(httpConnect:error:with:)]) { 
166.             [_delegate httpConnect:self error:error with:dicParam]; 
167.         } 
168.         [dicTask release]; 
169.         _numberOfHTTPConnection -= 1; 
170.     } 
171.      
172.     // 
173.     [self startHTTPConnection]; 
174. } 
175.  
176. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
177. { 
178.     HTTPLOG(@"网络请求收到响应"); 
179.     // 
180.     NSDictionary *dicTask = nil; 
181.     for (int i = 0; i < _marrayTaskDic.count; i++) { 
182.         NSDictionary *dic = [_marrayTaskDic objectAtIndex:i]; 
183.         //找到网络连接相应的数据字典 
184.         if ([dic objectForKey:@"connect"] == connection) { 
185.             dicTask = dic; 
186.             break; 
187.         } 
188.     } 
189.     // 
190.     if ([response isMemberOfClass:NSHTTPURLResponse.class]) { 
191.         NSHTTPURLResponse *responseHTTP = (NSHTTPURLResponse *)response; 
192.         NSUInteger statusCode = responseHTTP.statusCode; 
193.         NSDictionary *dicAllHeaderFields = responseHTTP.allHeaderFields; 
194.         NSDictionary *dicParam = [dicTask objectForKey:@"param"]; 
195.         //收到服务器返回的HTTP信息头 
196.         SEL receiveResponse = @selector(httpConnect:receiveResponseWithStatusCode:andAllHeaderFields:with:); 
197.         if ([self.delegate respondsToSelector:receiveResponse]) { 
198.             [self.delegate httpConnect:self receiveResponseWithStatusCode:statusCode  
199.                     andAllHeaderFields:dicAllHeaderFields with:dicParam]; 
200.         } 
201.     } 
202. } 
203.  
204. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
205. { 
206.     HTTPLOG(@"网络请求收到数据"); 
207.     // 
208.     NSDictionary *dicTask = nil; 
209.     for (int i = 0; i < _marrayTaskDic.count; i++) { 
210.         NSDictionary *dic = [_marrayTaskDic objectAtIndex:i]; 
211.         //找到网络连接相应的数据字典 
212.         if ([dic objectForKey:@"connect"] == connection) { 
213.             dicTask = dic; 
214.             break; 
215.         } 
216.     } 
217.      
218.     // 
219.     if (dicTask) { 
220.         //向缓存中添加数据 
221.         NSMutableData *mdataCache = [dicTask objectForKey:@"cache"]; 
222.         [mdataCache appendData:data]; 
223.         NSDictionary *dicParam = [dicTask objectForKey:@"param"]; 
224.         HTTPLOG(@"该数据的参数:%@", dicParam); 
225.         //收到部分数据 
226.         if ([self.delegate respondsToSelector:@selector(httpConnect:receiveData:with:)]) { 
227.             [self.delegate httpConnect:self receiveData:data with:dicParam]; 
228.         } 
229.     } 
230.     HTTPLOG(@"网络请求收到数据并处理完成"); 
231. } 
232.  
233. - (void)connectionDidFinishLoading:(NSURLConnection *)connection 
234. { 
235.     HTTPLOG(@"网络请求结束"); 
236.     // 
237.     NSDictionary *dicTask = nil; 
238.     for (int i = 0; i < _marrayTaskDic.count; i++) { 
239.         NSDictionary *dic = [_marrayTaskDic objectAtIndex:i]; 
240.         //找到网络连接相应的数据字典 
241.         if ([dic objectForKey:@"connect"] == connection) { 
242.             dicTask = dic; 
243.             break; 
244.         } 
245.     } 
246.      
247.     // 
248.     if (dicTask) { 
249.         [dicTask retain]; 
250.         //删除 
251.         [_marrayTaskDic removeObject:dicTask]; 
252.         NSData *dataCache = [dicTask objectForKey:@"cache"]; 
253.         NSDictionary *dicParam = [dicTask objectForKey:@"param"]; 
254.         if ([_delegate respondsToSelector:@selector(httpConnect:finish:with:)]) { 
255.             [_delegate httpConnect:self finish:dataCache with:dicParam]; 
256.         } 
257.         [dicTask release]; 
258.         _numberOfHTTPConnection -= 1; 
259.     } 
260.      
261.     [self startHTTPConnection]; 
262. } 
263.  
264.  
265. #pragma mark - Private 
266.  
267. - (void)startHTTPConnection 
268. { 
269.     if (_numberOfHTTPConnection < MAXNUMBER_HTTPCONNECTION) { 
270.         if (_numberOfHTTPConnection < _marrayTaskDic.count) { 
271.             NSDictionary *dicTask = [_marrayTaskDic objectAtIndex:_numberOfHTTPConnection]; 
272.             NSURLConnection *urlConnection = [dicTask objectForKey:@"connect"]; 
273.             [urlConnection start]; 
274.             // 
275.             _numberOfHTTPConnection += 1; 
276.         } 
277.     } 
278.     HTTPLOG(@"正在处理的网络请求数:%i,等待处理的网络请求:%i",  
279.             _numberOfHTTPConnection, _marrayTaskDic.count-_numberOfHTTPConnection); 
280. } 
281.  
282. @end   www.2cto.com

        这个类有四个接口,后两个是取消网络请求的,不必讨论。前两个是发起网络请求的,用的最多的就是这两个接口了。如果只是通过GET方法从服务器取数据,第一个接口足够了。当然也可以用第二个。如果需要用POST方式向服务器发送数据,得用第二个接口。
        第一个接口的第一个参数是URL字符串,第二个参数用来区分网络请求的,如果两次请求的第二个参数一样,第二次请求会被过滤掉。这个参数还有一个作用,就是协议回调函数的参数,用来让上层区分网络请求的。
        第二个接口的第一个参数是NSURLRequest类型,用来设置网络请求参数的,比如POST、要发送的数据流、HTTP信息头等。第二个参数的作用跟第一个接口的第二个参数一样。
        该类对应的协议就不必谈了,大家能看懂的。该类功能的具体实现,大家自己分析

0 0
原创粉丝点击