HBHttpImageDownloaderOperation.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. //
  2. // HBHttpImageDownloaderOperation.m
  3. // MyTest
  4. //
  5. // Created by weqia on 13-8-21.
  6. // Copyright (c) 2013年 weqia. All rights reserved.
  7. //
  8. #import "HBHttpImageDownloaderOperation.h"
  9. #import "HBHttp.h"
  10. @interface HBHttpImageDownloaderOperation ()
  11. {
  12. NSURL * _url;
  13. NSURLConnection * _connection;
  14. long long _expectedSize;
  15. BOOL _retry;
  16. }
  17. @property (nonatomic,strong) HBHttpImageDownloaderProcessBlock processBlock;
  18. @property (nonatomic,strong) HBHttpImageDownloaderCompleteBlock completeBlock;
  19. @property (nonatomic,strong) HBHttpImageDownloaderCancelBlock cancelBlock;
  20. @property (assign,nonatomic,getter = isFinished) BOOL finished;
  21. @property (assign,nonatomic,getter = isExecuting) BOOL executed;
  22. @property (assign,nonatomic,getter = isConcurrent) BOOL concurrent;
  23. @property (nonatomic,strong) NSMutableData * imgData;
  24. @end
  25. @implementation HBHttpImageDownloaderOperation
  26. #pragma -mark 接口方法
  27. -(id<HBHttpOperationDelegate>)initWithURL:(NSURL*)url
  28. options:(HBHttpImageDownloaderOption)option
  29. process:(HBHttpImageDownloaderProcessBlock)process
  30. complete:(HBHttpImageDownloaderCompleteBlock)complete
  31. cancel:(void(^)())cancel
  32. {
  33. self=[super init];
  34. if(self){
  35. _url=url;
  36. _option=option;
  37. _processBlock=[process copy];
  38. _completeBlock=[complete copy];
  39. _cancelBlock=[cancel copy];
  40. _request=[[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLCacheStorageNotAllowed timeoutInterval:17];
  41. _retry=NO;
  42. _executed=NO;
  43. }
  44. return self;
  45. }
  46. -(void)setFinished:(BOOL)finished
  47. {
  48. [self willChangeValueForKey:@"isFinished"];
  49. _finished=finished;
  50. [self didChangeValueForKey:@"isFinished"];
  51. }
  52. -(void)setExecuted:(BOOL)executed
  53. {
  54. [self willChangeValueForKey:@"isExecuted"];
  55. _executed=executed;
  56. [self didChangeValueForKey:@"isExecuted"];
  57. }
  58. -(void)setConcurrent:(BOOL)concurrent
  59. {
  60. [self willChangeValueForKey:@"isConcurrent"];
  61. _concurrent=concurrent;
  62. [self didChangeValueForKey:@"isConcurrent"];
  63. }
  64. #pragma -mark 私有方法
  65. -(void)retry
  66. {
  67. if(!_retry){
  68. [self start];
  69. _retry=YES;
  70. }
  71. }
  72. -(void)start
  73. {
  74. if(self.isCancelled){
  75. _finished=YES;
  76. _executed=NO;
  77. [self reset];
  78. return;
  79. }
  80. if(!_request){
  81. if(_completeBlock){
  82. _completeBlock(nil,nil,[NSError errorWithDomain:NSURLErrorDomain code:HBHttpConnectionError userInfo:@{NSLocalizedDescriptionKey:Localized(@"JX_ReplyCreatFiled")}],NO);
  83. }
  84. return;
  85. }
  86. _executed=YES;
  87. _finished=NO;
  88. NSURLConnection * connection=[[NSURLConnection alloc]initWithRequest:_request delegate:self startImmediately:YES];
  89. _connection=connection;
  90. if(connection){
  91. if(_processBlock)
  92. _processBlock(0,-1); //标志图片下载已经开始
  93. /****发送开始下载图片的通知***/
  94. [g_notify postNotificationName:HBHttpImageDownloadStartNotification object:_url];
  95. }
  96. else{
  97. if(_completeBlock)
  98. /*****连接创建失败,返回错误信息******/
  99. _completeBlock(nil,nil,[NSError errorWithDomain:NSURLErrorDomain code:HBHttpConnectionError userInfo:@{NSLocalizedDescriptionKey:Localized(@"JX_ContionCreatFiled")}],NO);
  100. return;
  101. }
  102. CFRunLoopRun();
  103. }
  104. -(void)reset
  105. {
  106. _processBlock=nil;
  107. _completeBlock=nil;
  108. _cancelBlock=nil;
  109. _imgData=nil;
  110. _url=nil;
  111. _connection=nil;
  112. }
  113. -(void)done
  114. {
  115. [self reset];
  116. _finished=YES;
  117. _executed=NO;
  118. }
  119. #pragma -mark 回调方法
  120. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
  121. if(_completeBlock)
  122. _completeBlock(nil,nil,[NSError errorWithDomain:NSURLErrorDomain code:HBHttpDownloadError userInfo:@{NSLocalizedDescriptionKey:Localized(@"JX_ImageDownloadFiled")}],NO);
  123. [g_notify postNotificationName:HBHttpImageDownloadStopNotification object:_url];
  124. CFRunLoopStop(CFRunLoopGetCurrent());
  125. [self done];
  126. }
  127. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
  128. NSUInteger length= [data length];
  129. if(length>0&&_processBlock){
  130. _processBlock(length,_expectedSize);
  131. }
  132. [self.imgData appendData:data];
  133. }
  134. - (void)connectionDidFinishLoading:(NSURLConnection *)connection{
  135. UIImage * image=[UIImage imageWithData:self.imgData];
  136. BOOL success=(image!=nil);
  137. if(_completeBlock){
  138. _completeBlock(image,self.imgData,nil,success);
  139. }
  140. [g_notify postNotificationName:HBHttpImageDownloadStopNotification object:_url];
  141. CFRunLoopStop(CFRunLoopGetCurrent());
  142. [self done];
  143. }
  144. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
  145. /***如果响应没有出错,则开始接受数据***/
  146. if(![response respondsToSelector:@selector(statusCode)]||[((NSHTTPURLResponse*)response) statusCode]<400){
  147. _expectedSize=[response expectedContentLength];
  148. if(_expectedSize>0){
  149. if(_processBlock)
  150. _processBlock(0,_expectedSize);
  151. self.imgData=[[NSMutableData alloc]initWithCapacity:_expectedSize];
  152. return;
  153. }
  154. }
  155. /****如果出错,则停止下载***/
  156. CFRunLoopStop(CFRunLoopGetCurrent());
  157. if(_completeBlock){
  158. _completeBlock(nil,nil,[NSError errorWithDomain:NSURLErrorDomain code:[((NSHTTPURLResponse*)response) statusCode] userInfo:@{NSLocalizedDescriptionKey: Localized(@"JX_ImageIsNull")}],NO);
  159. }
  160. [g_notify postNotificationName:HBHttpImageDownloadStopNotification object:_url];
  161. [self done];
  162. }
  163. -(void)cancel
  164. {
  165. if(self.isCancelled||self.isFinished)return;
  166. if(_cancelBlock)
  167. _cancelBlock();
  168. [super cancel];
  169. if(_connection){
  170. [_connection cancel];
  171. }
  172. CFRunLoopStop(CFRunLoopGetCurrent());
  173. [g_notify postNotificationName:HBHttpImageDownloadStopNotification object:_url];
  174. [self done];
  175. }
  176. -(BOOL)isFinished{
  177. return _finished;
  178. }
  179. -(BOOL)isConcurrent{
  180. return _concurrent;
  181. }
  182. @end