KBDownloadFile.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. //
  2. // KBYTDownloadStream.m
  3. // Seas0nPass
  4. //
  5. // Created by Kevin Bradley on 3/9/07.
  6. // Copyright 2007 nito, LLC. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. /*
  10. class adapted from hawkeye's KBYTDownloadStream class for downloading youtube files, largely pruned to remove irrelevant sections + updated to cancel the xfer + remodified/updated to use blocks instead of antiquated delegate methods.
  11. */
  12. #import "KBDownloadFile.h"
  13. @implementation KBDownloadFile
  14. @synthesize downloadLocation;
  15. #pragma mark -
  16. #pragma mark •• URL code
  17. - (void)dealloc
  18. {
  19. downloadLocation = nil;
  20. }
  21. - (void)cancel
  22. {
  23. NSError *theError = nil;
  24. [self download:urlDownload didFailWithError:theError];
  25. [urlDownload cancel];
  26. }
  27. - (long long)updateFrequency
  28. {
  29. return updateFrequency;
  30. }
  31. - (void)setUpdateFrequency:(long long)newUpdateFrequency
  32. {
  33. updateFrequency = newUpdateFrequency;
  34. }
  35. - (id)init
  36. {
  37. if(self = [super init]) {
  38. [self setUpdateFrequency:1];
  39. }
  40. return self;
  41. }
  42. - (void)downloadURL:(NSURL *)url toLocation:(NSString *)dlLocation
  43. progress:(DownloadProgressBlock)progressBlock
  44. completed:(DownloadCompletedBlock)completedBlock
  45. {
  46. self.CompletedBlock = completedBlock;
  47. self.ProgressBlock = progressBlock;
  48. self.downloadLocation = dlLocation;
  49. NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @"com.nito.installer"];
  50. // Creating sessions
  51. NSOperationQueue *operationQueue = [NSOperationQueue mainQueue];
  52. NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration delegate:self delegateQueue:operationQueue];
  53. NSURLSessionDownloadTask *downloadTask = [backgroundSession downloadTaskWithURL:url];
  54. [downloadTask resume];
  55. }
  56. - (void)URLSession:(NSURLSession *)session
  57. downloadTask:(NSURLSessionDownloadTask *)downloadTask
  58. didWriteData:(int64_t)bytesWritten
  59. totalBytesWritten:(int64_t)totalBytesWritten
  60. totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
  61. {
  62. //NSLog(@"Session %@ download task %@ wrote an additional %lld bytes (total %lld bytes) out of an expected %lld bytes.\n", session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
  63. if (totalBytesExpectedToWrite != NSURLResponseUnknownLength) {
  64. double percentComplete=(totalBytesWritten/(float)totalBytesExpectedToWrite)*100.0;
  65. // NSLog(@"Percent complete - %f",percentComplete);
  66. if((freq%updateFrequency) == 0){
  67. if (self.ProgressBlock != nil)
  68. {
  69. self.ProgressBlock(percentComplete);
  70. }
  71. if (self.FancyProgressBlock != nil)
  72. {
  73. NSString *mediaType = @"media";
  74. NSString *pathExt = downloadLocation.pathExtension;
  75. if ([pathExt isEqualToString:@"m4v"])
  76. {
  77. mediaType = @"video";
  78. } else if ([pathExt isEqualToString:@"aac"])
  79. {
  80. mediaType = @"audio";
  81. }
  82. self.FancyProgressBlock(percentComplete, [NSString stringWithFormat:@"Downloading %@ file...", mediaType]);
  83. }
  84. }
  85. freq++;
  86. } else {
  87. NSLog(@"Bytes received - %lld",totalBytesWritten);
  88. }
  89. }
  90. - (void)URLSession:(NSURLSession *)session
  91. downloadTask:(NSURLSessionDownloadTask *)downloadTask
  92. didResumeAtOffset:(int64_t)fileOffset
  93. expectedTotalBytes:(int64_t)expectedTotalBytes
  94. {
  95. NSLog(@"Session %@ download task %@ resumed at offset %lld bytes out of an expected %lld bytes.\n", session, downloadTask, fileOffset, expectedTotalBytes);
  96. }
  97. - (void)URLSession:(NSURLSession *)session
  98. downloadTask:(NSURLSessionDownloadTask *)downloadTask
  99. didFinishDownloadingToURL:(NSURL *)location
  100. {
  101. NSLog(@"Session %@ download task %@ finished downloading to URL %@\n", session, downloadTask, location);
  102. // Perform the completion handler for the current session
  103. //self.completionHandlers[session.configuration.identifier]();
  104. // Open the downloaded file for reading
  105. //NSError *readError = nil;
  106. //NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:location error:&readError];
  107. // ...
  108. // Move the file to a new URL
  109. NSFileManager *fileManager = [NSFileManager defaultManager];
  110. //NSURL *cacheDirectory = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] firstObject];
  111. NSError *moveError = nil;
  112. if ([fileManager fileExistsAtPath:self.downloadLocation])
  113. {
  114. [fileManager removeItemAtPath:self.downloadLocation error:nil];
  115. }
  116. if ([fileManager moveItemAtPath:location.path toPath:self.downloadLocation error:&moveError])
  117. {
  118. self.CompletedBlock(self.downloadLocation);
  119. } else {
  120. NSLog(@"error: %@", moveError);
  121. }
  122. /*
  123. if ([fileManager moveItemAtURL:location toURL:cacheDirectory error:&moveError]) {
  124. // ...
  125. }
  126. */
  127. }
  128. //deprecated / obsolete, SHOULD still work but should never be used.
  129. - (void)downloadFileWithURL:(NSURL *)url
  130. toLocation:(NSString *)dlLocation
  131. progress:(DownloadProgressBlock)progressBlock
  132. completed:(DownloadCompletedBlock)completedBlock
  133. {
  134. self.CompletedBlock = completedBlock;
  135. self.ProgressBlock = progressBlock;
  136. self.downloadLocation = dlLocation;
  137. NSURLRequest *theRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
  138. urlDownload = [[NSURLDownload alloc] initWithRequest:theRequest delegate:self];
  139. [urlDownload setDestination:downloadLocation allowOverwrite:YES];
  140. }
  141. - (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error
  142. {
  143. NSLog(@"error: %@", error);
  144. //[handler downloadFailed:downloadLocation];
  145. }
  146. - (void)downloadDidFinish:(NSURLDownload *)download
  147. {
  148. if(download == urlDownload) {
  149. if (self.CompletedBlock != nil)
  150. {
  151. self.CompletedBlock(downloadLocation);
  152. }
  153. }
  154. }
  155. - (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response
  156. {
  157. bytesReceived=0;
  158. [self setDownloadResponse:response];
  159. }
  160. - (void)setDownloadResponse:(NSURLResponse *)response
  161. {
  162. myResponse = response;
  163. }
  164. - (NSURLResponse *)downloadResponse
  165. {
  166. return myResponse;
  167. }
  168. - (void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length
  169. {
  170. long long expectedLength = [[self downloadResponse] expectedContentLength];
  171. bytesReceived=bytesReceived+length;
  172. if (expectedLength != NSURLResponseUnknownLength) {
  173. double percentComplete=(bytesReceived/(float)expectedLength)*100.0;
  174. // NSLog(@"Percent complete - %f",percentComplete);
  175. if((freq%updateFrequency) == 0){
  176. if (self.ProgressBlock != nil)
  177. {
  178. self.ProgressBlock(percentComplete);
  179. }
  180. if (self.FancyProgressBlock != nil)
  181. {
  182. NSString *mediaType = @"media";
  183. NSString *pathExt = downloadLocation.pathExtension;
  184. if ([pathExt isEqualToString:@"m4v"])
  185. {
  186. mediaType = @"video";
  187. } else if ([pathExt isEqualToString:@"aac"])
  188. {
  189. mediaType = @"audio";
  190. }
  191. self.FancyProgressBlock(percentComplete, [NSString stringWithFormat:@"Downloading %@ file...", mediaType]);
  192. }
  193. }
  194. freq++;
  195. } else {
  196. NSLog(@"Bytes received - %f",bytesReceived);
  197. }
  198. }
  199. @end