URLDownloader.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. //
  2. // Downloader.m
  3. // iOS-URLDownloader
  4. //
  5. // Created by Kristijan Sedlak on 7/21/11.
  6. // Copyright 2011 AppStrides. All rights reserved.
  7. //
  8. #import "URLDownloader.h"
  9. #import <UIKit/UIKit.h>
  10. #pragma mark -
  11. @interface URLDownloader()
  12. @property(retain) NSURLConnection *urlConnection;
  13. @property(retain) NSURLResponse *urlResponse;
  14. @property(retain) NSMutableData *urlData;
  15. @property(retain) URLCredential *urlCredential;
  16. @end
  17. #pragma mark -
  18. @implementation URLDownloader
  19. @synthesize delegate;
  20. @synthesize state;
  21. @synthesize urlConnection;
  22. @synthesize urlResponse;
  23. @synthesize urlData;
  24. @synthesize urlCredential;
  25. #pragma mark Setters
  26. - (void)setState:(URLDownloaderState)downloaderState
  27. {
  28. if (downloaderState != state)
  29. {
  30. state = downloaderState;
  31. if ([self.delegate respondsToSelector:@selector(urlDownloader:didChangeStateTo:)])
  32. {
  33. [self.delegate urlDownloader:self didChangeStateTo:downloaderState];
  34. }
  35. }
  36. }
  37. #pragma mark General
  38. - (void)dealloc
  39. {
  40. [urlConnection cancel];
  41. }
  42. - (id)initWithDelegate:(id)obj
  43. {
  44. if(self == [self init])
  45. {
  46. self.delegate = obj;
  47. [self setState:URLDownloaderStateInactive];
  48. }
  49. return self;
  50. }
  51. + (id)downloaderWithDelegate:(id)obj
  52. {
  53. return [[URLDownloader alloc] initWithDelegate:obj];
  54. }
  55. - (void)reset
  56. {
  57. }
  58. #pragma mark Actions
  59. - (void)downloadFileWithURL:(NSURL *)url
  60. toLocation:(NSString *)dlLocation
  61. withCredential:(URLCredential *)credential
  62. completed:(DownloadCompletedBlock)completedBlock
  63. {
  64. NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
  65. self.urlCredential = credential;
  66. self.urlResponse = nil;
  67. self.urlData = [[NSMutableData alloc] init];
  68. self.downloadLocation = dlLocation;
  69. #pragma clang diagnostic push
  70. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  71. self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
  72. #pragma clang diagnostic pop
  73. self.CompletedBlock = completedBlock;
  74. [self.urlConnection start];
  75. OurLog(@"[URLDownloader] Download started");
  76. }
  77. - (void)download:(NSURLRequest *)request withCredential:(URLCredential *)credential
  78. {
  79. [self setState:URLDownloaderStateConnecting];
  80. self.urlCredential = credential;
  81. self.urlResponse = nil;
  82. self.urlData = [[NSMutableData alloc] init];
  83. #pragma clang diagnostic push
  84. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  85. self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
  86. #pragma clang diagnostic pop
  87. [self.urlConnection start];
  88. #if TARGET_OS_IOS
  89. [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
  90. #endif
  91. OurLog(@"[URLDownloader] Download started");
  92. }
  93. - (void)cancel
  94. {
  95. [urlConnection cancel];
  96. OurLog(@"[URLDownloader] Download canceled");
  97. if ([self.delegate respondsToSelector:@selector(urlDownloaderDidCancelDownloading:)])
  98. {
  99. [self.delegate urlDownloaderDidCancelDownloading:self];
  100. }
  101. [self setState:URLDownloaderStateCanceled];
  102. if (self.CompletedBlock != nil){
  103. self.CompletedBlock(nil);
  104. }
  105. }
  106. #pragma mark Information
  107. - (int)fullContentSize
  108. {
  109. @try
  110. {
  111. return [[NSNumber numberWithLongLong:[urlResponse expectedContentLength]] intValue];
  112. }
  113. @catch (NSException * e)
  114. {
  115. return 0;
  116. }
  117. }
  118. - (int)downloadedContentSize
  119. {
  120. @try
  121. {
  122. return [[NSNumber numberWithInteger:[self.urlData length]] intValue];
  123. }
  124. @catch (NSException * e)
  125. {
  126. return 0;
  127. }
  128. }
  129. - (float)downloadCompleteProcent
  130. {
  131. float contentSize = [self fullContentSize];
  132. float downloadedSize = [self downloadedContentSize];
  133. return contentSize > 0.0 ? downloadedSize / contentSize : 0.0;
  134. }
  135. #pragma mark Connection
  136. - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
  137. {
  138. [self setState:URLDownloaderStateAuthenticating];
  139. if ([challenge previousFailureCount] == 0)
  140. {
  141. OurLog(@"[URLDownloader] Authentication challenge received");
  142. NSURLCredential *credential = [NSURLCredential credentialWithUser:self.urlCredential.username
  143. password:self.urlCredential.password
  144. persistence:self.urlCredential.persistance];
  145. [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
  146. OurLog(@"[URLDownloader] Credentials sent");
  147. }
  148. else
  149. {
  150. // [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
  151. OurLog(@"[URLDownloader] Authentication failed");
  152. [self.delegate urlDownloader:self didFailOnAuthenticationChallenge:challenge];
  153. }
  154. }
  155. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
  156. {
  157. self.urlResponse = response;
  158. [self.urlData setLength:0]; // in case of 302
  159. [self setState:URLDownloaderStateDownloading];
  160. OurLog(@"[URLDownloader] Downloading %@ ...", [[response URL] absoluteString]);
  161. if ([self.delegate respondsToSelector:@selector(urlDownloaderDidStart:)])
  162. {
  163. [self.delegate urlDownloaderDidStart:self];
  164. }
  165. }
  166. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  167. {
  168. [self.urlData appendData:data];
  169. if ([self.delegate respondsToSelector:@selector(urlDownloader:didReceiveData:)])
  170. {
  171. [self.delegate urlDownloader:self didReceiveData:data];
  172. }
  173. }
  174. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
  175. {
  176. [self setState:URLDownloaderStateInactive];
  177. OurLog(@"[URLDownloader] Error: %@, %ld", error, (long)[error code]);
  178. switch ([error code])
  179. {
  180. case NSURLErrorNotConnectedToInternet:
  181. [self.delegate urlDownloader:self didFailWithNotConnectedToInternetError:error];
  182. break;
  183. default:
  184. [self.delegate urlDownloader:self didFailWithError:error];;
  185. break;
  186. }
  187. if (self.CompletedBlock != nil){
  188. self.CompletedBlock(nil);
  189. }
  190. }
  191. - (void)connectionDidFinishLoading:(NSURLConnection *)connection
  192. {
  193. OurLog(@"[URLDownloader] Download finished");
  194. NSData *data = [NSData dataWithData:self.urlData];
  195. if ([self.delegate respondsToSelector:@selector(urlDownloader:didFinishWithData:)])
  196. {
  197. [self.delegate urlDownloader:self didFinishWithData:data];
  198. }
  199. [data writeToFile:[self downloadLocation] atomically:NO];
  200. [self setState:URLDownloaderStateFinished];
  201. if (self.CompletedBlock != nil){
  202. self.CompletedBlock([self downloadLocation]);
  203. }
  204. }
  205. @end