From d2db8889aa93d397109eea6bca2b6a3b20516aca Mon Sep 17 00:00:00 2001 From: "i.mustakaev@qiwi.ru" Date: Fri, 13 Nov 2015 16:45:54 +0300 Subject: [PATCH] add variable buffer size --- .../TCBlobDownload/TCBlobDownloadManager.h | 11 ++++++++ .../TCBlobDownload/TCBlobDownloadManager.m | 27 +++++++++++++++++-- .../TCBlobDownload/TCBlobDownloader.h | 5 +++- .../TCBlobDownload/TCBlobDownloader.m | 6 +++-- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/TCBlobDownload/TCBlobDownload/TCBlobDownloadManager.h b/TCBlobDownload/TCBlobDownload/TCBlobDownloadManager.h index 84fa3542..401e127e 100644 --- a/TCBlobDownload/TCBlobDownload/TCBlobDownloadManager.h +++ b/TCBlobDownload/TCBlobDownload/TCBlobDownloadManager.h @@ -96,6 +96,17 @@ error:(void (^)(NSError *error))errorBlock complete:(void (^)(BOOL downloadFinished, NSString *pathToFile))completeBlock; +/** + * @param bufferSizeKb - save download state every "bufferSizeKb" kilobytes for this file. + * */ +- (TCBlobDownloader *)startDownloadWithURL:(NSURL *)url + customPath:(NSString *)customPathOrNil + firstResponse:(void (^)(NSURLResponse *response))firstResponseBlock + progress:(void (^)(uint64_t receivedLength, uint64_t totalLength, NSInteger remainingTime, float progress))progressBlock + error:(void (^)(NSError *error))errorBlock + complete:(void (^)(BOOL downloadFinished, NSString *pathToFile))completeBlock + bufferSizeKb:(NSUInteger)bufferSizeKb; + /** Starts an already instanciated `TCBlobDownloader` object. diff --git a/TCBlobDownload/TCBlobDownload/TCBlobDownloadManager.m b/TCBlobDownload/TCBlobDownload/TCBlobDownloadManager.m index a4de341e..1efdcdfb 100644 --- a/TCBlobDownload/TCBlobDownload/TCBlobDownloadManager.m +++ b/TCBlobDownload/TCBlobDownload/TCBlobDownloadManager.m @@ -5,6 +5,8 @@ // Copyright (c) 2013 Thibault Charbonnier. All rights reserved. // +static double const kDefaultBufferSizeKb = 1024; // 1 MB + #import "TCBlobDownloadManager.h" #import "TCBlobDownloader.h" @@ -66,6 +68,25 @@ - (TCBlobDownloader *)startDownloadWithURL:(NSURL *)url error:(void (^)(NSError *error))errorBlock complete:(void (^)(BOOL downloadFinished, NSString *pathToFile))completeBlock { + + TCBlobDownloader *downloader = [self startDownloadWithURL:url + customPath:customPathOrNil + firstResponse:firstResponseBlock + progress:progressBlock + error:errorBlock + complete:completeBlock + bufferSizeKb:kDefaultBufferSizeKb]; + + return downloader; +} + +- (TCBlobDownloader *)startDownloadWithURL:(NSURL *)url + customPath:(NSString *)customPathOrNil + firstResponse:(void (^)(NSURLResponse *response))firstResponseBlock + progress:(void (^)(uint64_t receivedLength, uint64_t totalLength, NSInteger remainingTime, float progress))progressBlock + error:(void (^)(NSError *error))errorBlock complete:(void (^)(BOOL downloadFinished, NSString *pathToFile))completeBlock + bufferSizeKb:(NSUInteger)bufferSizeKb { + NSString *downloadPath = customPathOrNil ? customPathOrNil : self.defaultDownloadPath; TCBlobDownloader *downloader = [[TCBlobDownloader alloc] initWithURL:url @@ -73,9 +94,11 @@ - (TCBlobDownloader *)startDownloadWithURL:(NSURL *)url firstResponse:firstResponseBlock progress:progressBlock error:errorBlock - complete:completeBlock]; - [self.operationQueue addOperation:downloader]; + complete:completeBlock + bufferSizeKb:bufferSizeKb]; + + [self.operationQueue addOperation:downloader]; return downloader; } diff --git a/TCBlobDownload/TCBlobDownload/TCBlobDownloader.h b/TCBlobDownload/TCBlobDownload/TCBlobDownloader.h index 8732a1fe..49b9a2c8 100644 --- a/TCBlobDownload/TCBlobDownload/TCBlobDownloader.h +++ b/TCBlobDownload/TCBlobDownload/TCBlobDownloader.h @@ -30,6 +30,7 @@ extern NSString * const TCBlobDownloadErrorHTTPStatusKey; */ extern NSString * const TCBlobDownloadErrorDomain; +static const NSUInteger byte = 1024; /** The possible error codes for a `TCBlobDownloader` operation. When an error block or the corresponding delegate method are called, an `NSError` instance is passed as parameter. If the domain of this `NSError` is TCBlobDownload's, the `code` parameter will be set to one of these values. @@ -190,6 +191,7 @@ typedef NS_ENUM(NSUInteger, TCBlobDownloadState) { @param progressBlock This block is called on each response from the server while the download is occurring. Can be `nil`. If the remaining time has not been calculated yet, the value is `-1`. @param errorBlock Called when an error occur during the download. If this block is called, the download will be cancelled just after. Can be `nil`. @param completeBlock Called when the download is completed or cancelled. Can be `nil`. If the download has been cancelled with the parameter `removeFile` set to `YES`, then the `pathToFile` parameter is `nil`. The `TCBlobDownloader` operation will be removed from `TCBlobDownloadManager` just after this block is called. + * @param bufferSizeBytes - save download state every "bufferSizeBytes" for this file. @return The newly created `TCBlobDownloader`. @since 1.3 @@ -199,7 +201,8 @@ typedef NS_ENUM(NSUInteger, TCBlobDownloadState) { firstResponse:(void (^)(NSURLResponse *response))firstResponseBlock progress:(void (^)(uint64_t receivedLength, uint64_t totalLength, NSInteger remainingTime, float progress))progressBlock error:(void (^)(NSError *error))errorBlock - complete:(void (^)(BOOL downloadFinished, NSString *pathToFile))completeBlock; + complete:(void (^)(BOOL downloadFinished, NSString *pathToFile))completeBlock + bufferSizeKb:(NSUInteger)bufferSizeKb; /** Cancels the download. Remove already downloaded parts of the file from the disk is asked. diff --git a/TCBlobDownload/TCBlobDownload/TCBlobDownloader.m b/TCBlobDownload/TCBlobDownload/TCBlobDownloader.m index a9cc061c..75413517 100644 --- a/TCBlobDownload/TCBlobDownload/TCBlobDownloader.m +++ b/TCBlobDownload/TCBlobDownload/TCBlobDownloader.m @@ -5,7 +5,6 @@ // Copyright (c) 2013 Thibault Charbonnier. All rights reserved. // -static const double kBufferSize = 1000*1000; // 1 MB static const NSTimeInterval kDefaultRequestTimeout = 30; static const NSInteger kNumberOfSamples = 5; @@ -25,6 +24,7 @@ @interface TCBlobDownloader () @property (nonatomic, strong) NSURLConnection *connection; @property (nonatomic, strong) NSMutableData *receivedDataBuffer; @property (nonatomic, strong) NSFileHandle *file; +@property(nonatomic) NSUInteger bufferSizeBytes; // Speed rate and remaining time @property (nonatomic, strong) NSTimer *speedTimer; @property (nonatomic, strong) NSMutableArray *samplesOfDownloadedBytes; @@ -87,6 +87,7 @@ - (instancetype)initWithURL:(NSURL *)url progress:(void (^)(uint64_t receivedLength, uint64_t totalLength, NSInteger remainingTime, float progress))progressBlock error:(void (^)(NSError *error))errorBlock complete:(void (^)(BOOL downloadFinished, NSString *pathToFile))completeBlock + bufferSizeKb:(NSUInteger)bufferSizeKb { self = [self initWithURL:url downloadPath:pathToDL delegate:nil]; if (self) { @@ -94,6 +95,7 @@ - (instancetype)initWithURL:(NSURL *)url self.progressBlock = progressBlock; self.errorBlock = errorBlock; self.completeBlock = completeBlock; + self.bufferSizeBytes = bufferSizeKb * byte; } return self; } @@ -247,7 +249,7 @@ - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData *)data (float) self.receivedDataLength / self.expectedDataLength * 100, (long) self.receivedDataLength, (long) self.expectedDataLength); - if (self.receivedDataBuffer.length > kBufferSize && [self isExecuting]) { + if (self.receivedDataBuffer.length > self.bufferSizeBytes && [self isExecuting]) { [self.file writeData:self.receivedDataBuffer]; [self.receivedDataBuffer setData:nil]; }