2

I am not sure where I am going wrong. I have to download a file back to back, i.e., when ever I trigger the new download. Always second download should happen after first download. I have to use NSOperationQueues to achieve this.

I am using maxConcurrentOperationCount = 1, assuming that the downloads will happen serially. But when I see the log, downloads are happening concurrently.

Second, third requests are getting executed, while first request download is happening.

How can I achieve the execution order in FIFO ?

Here is the code and the log. any help is highly appreciated. Thanks in advance.

Code:

#import "ViewController.h"
#import "AFNetworking.h"

//#define DOCUMENT_DIRECTORY_PATH [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]
#define DOCUMENT_DIRECTORY_URL [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]
#define CACHE_DIRECTORY_PATH [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]

#define URL_DOWNLOAD_ZIP_6KB    @"https://codeload.github.com/H2CO3/HCDownload/zip/master"
#define URL_DOWNLOAD_ZIP_37KB   @"https://s3.amazonaws.com/hayageek/downloads/ios/apns.zip"
#define URL_DOWNLOAD_ZIP_633KB  @"http://cdn1.raywenderlich.com/wp-content/uploads/2015/09/VacationSpots_Complete.zip"
#define URL_DOWNLOAD_ZIP_686KB  @"http://cdn3.raywenderlich.com/wp-content/uploads/2014/01/Weather_Final.zip"
#define URL_DOWNLOAD_ZIP_215KB  @"http://cdn4.raywenderlich.com/wp-content/uploads/2014/01/GooglyPuff_Start_1.zip"

@interface ViewController () {
    int counter ;
    NSOperationQueue *zipFileDownloadQueue ;    
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    counter = 0 ;

    zipFileDownloadQueue = [[NSOperationQueue alloc] init] ;
    zipFileDownloadQueue.maxConcurrentOperationCount = 1 ;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)downloadBtnTapped:(id)sender {
//    NSLog(@"Download button tapped: %d", counter) ;

    NSURL *url ;

    if (counter == 5) {
        counter = 0;
    }

    ++counter ;

    if (counter == 1) {
        url = [NSURL URLWithString:URL_DOWNLOAD_ZIP_6KB];
    } else if (counter == 2) {
        url = [NSURL URLWithString:URL_DOWNLOAD_ZIP_633KB];
    } else if (counter == 3) {
        url = [NSURL URLWithString:URL_DOWNLOAD_ZIP_686KB];
    } else if (counter == 4) {
        url = [NSURL URLWithString:URL_DOWNLOAD_ZIP_215KB];
    } else if (counter == 5) {
        url = [NSURL URLWithString:URL_DOWNLOAD_ZIP_37KB];
    }

// #1
    NSInvocationOperation *fileDownloadOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startDownloadingZipFileAtUrl:) object:url] ;
    [zipFileDownloadQueue addOperation:fileDownloadOperation] ;
}

- (void)startDownloadingZipFileAtUrl:(NSURL *)url {
    NSLog(@"Downloading file : %@", [url lastPathComponent]) ;

    AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager] ;

    //for progress
    [sessionManager setDownloadTaskDidWriteDataBlock:^(NSURLSession * _Nonnull session, NSURLSessionDownloadTask * _Nonnull downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
        float progress = (((float)totalBytesWritten) / totalBytesExpectedToWrite) * 100;
        NSLog(@"File :%@ Progress: %f percent", [url lastPathComponent], progress) ;
    }] ;

    //For downloading
    NSURLSessionTask *downloadZipFile =
    [sessionManager downloadTaskWithRequest:[NSURLRequest requestWithURL:url]
                                   progress:nil
                                destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
                                    return [DOCUMENT_DIRECTORY_URL URLByAppendingPathComponent:[response suggestedFilename]];
                                } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
                                    NSLog(@"Downloaded file path : %@", filePath) ;

                                }] ;
    [downloadZipFile resume] ;
}

@end

Log:

2016-03-03 00:59:54.867 WebservicePOC[23364:1679678] Downloading file : master 2016-03-03 00:59:56.127 WebservicePOC[23364:1679673] Downloading file : VacationSpots_Complete.zip 2016-03-03 00:59:56.822 WebservicePOC[23364:1679673] File :VacationSpots_Complete.zip Progress: 0.228680 percent 2016-03-03 00:59:57.257 WebservicePOC[23364:1679736] Downloading file : Weather_Final.zip 2016-03-03 00:59:57.357 WebservicePOC[23364:1679678] File :VacationSpots_Complete.zip Progress: 0.457359 percent 2016-03-03 00:59:57.490 WebservicePOC[23364:1679676] File :Weather_Final.zip Progress: 0.139399 percent 2016-03-03 00:59:57.954 WebservicePOC[23364:1679673] File :VacationSpots_Complete.zip Progress: 0.686039 percent 2016-03-03 00:59:58.023 WebservicePOC[23364:1679676] File :Weather_Final.zip Progress: 0.350538 percent 2016-03-03 00:59:58.664 WebservicePOC[23364:1679676] File :master Progress: 34.184551 percent 2016-03-03 00:59:59.483 WebservicePOC[23364:1679779] File :master Progress: 55.647816 percent 2016-03-03 00:59:59.483 WebservicePOC[23364:1679736] File :Weather_Final.zip Progress: 0.561678 percent 2016-03-03 00:59:59.579 WebservicePOC[23364:1679676] File :master Progress: 100.000000 percent 2016-03-03 00:59:59.699 WebservicePOC[23364:1679676] File :Weather_Final.zip Progress: 0.772818 percent 2016-03-03 01:00:00.200 WebservicePOC[23364:1679676] File :Weather_Final.zip Progress: 0.983957 percent 2016-03-03 01:00:00.560 WebservicePOC[23364:1679736] File :Weather_Final.zip Progress: 1.195097 percent 2016-03-03 01:00:01.023 WebservicePOC[23364:1679779] File :Weather_Final.zip Progress: 1.406237 percent 2016-03-03 01:00:01.483 WebservicePOC[23364:1679678] File :Weather_Final.zip Progress: 2.250795 percent 2016-03-03 01:00:01.819 WebservicePOC[23364:1679779] File :Weather_Final.zip Progress: 2.673075 percent 2016-03-03 01:00:02.330 WebservicePOC[23364:1679678] File :Weather_Final.zip Progress: 3.306494 percent 2016-03-03 01:00:02.793 WebservicePOC[23364:1679779] File :Weather_Final.zip Progress: 3.517633 percent 2016-03-03 01:00:03.303 WebservicePOC[23364:1679779] File :Weather_Final.zip Progress: 4.573332 percent 2016-03-03 01:00:03.428 WebservicePOC[23364:1679736] File :Weather_Final.zip Progress: 4.784471 percent 2016-03-03 01:00:04.194 WebservicePOC[23364:1679678] File :Weather_Final.zip Progress: 5.417891 percent 2016-03-03 01:00:04.706 WebservicePOC[23364:1679736] File :VacationSpots_Complete.zip Progress: 0.914719 percent 2016-03-03 01:00:05.604 WebservicePOC[23364:1679736] File :Weather_Final.zip Progress: 5.629030 percent 2016-03-03 01:00:06.235 WebservicePOC[23364:1679678] File :Weather_Final.zip Progress: 5.840169 percent

Sravan
  • 1,891
  • 4
  • 23
  • 28

1 Answers1

0

The problem you are having is that you are setting the maximum concurrent count on the operation queue that is running the startDownloadingZipFileAtUrl method. That method launches a download in a different thread and then returns, allowing your operationqueue to run the next task (start another download).

What you need to be doing is setting the maximum concurrent task limit on the download queue. AFNetworking doesn't have a built in way of doing this (reference). Your tasks do have a completionHandler where you can start the next download. Since that's already built in for you it may be the easiest way. Otherwise check the reference a few sentences back and see if any of those options work for you.

Community
  • 1
  • 1
Putz1103
  • 6,211
  • 1
  • 18
  • 25
  • This means, `maxConcurrentOperationCount` has no weight when using `AFNetworking`? – Sravan Mar 02 '16 at 19:59
  • Yes and no. The way you are using it has absolutely nothing to do with AFNetworking. You are using `maxConcurrentOperationCount` on an OperationQueue entirely outside of AFNetworking, so it has no affect on AFNetworking's internal Task list. And AFNetworking works based on Tasks instead of operations, so it has no OperationQueue to set a limit on. – Putz1103 Mar 02 '16 at 20:05
  • A queue can be added to `AFNetworking`'s Queue ? In My app, I'll create one queue for serial download and another queue for Concurrent downloads. Can these two queues can be added to `AFNetworking`'s Queue? How can I achieve this ? – Sravan Mar 04 '16 at 06:15