Download many files (photos, videos) in background with priority order
Asked Answered
H

2

10

At first start of app I want to download all files from server and I want to continue in downloading even when user leaves app (it's not in foreground). The files I need to download are thumbnails, photos in original size, other files and video. I want to download them in order as I wrote before.

I am using Alamofire and I set session manager:

let backgroundManager: Alamofire.SessionManager = {
    let bundleIdentifier = "com....."
    return Alamofire.SessionManager(
      configuration: URLSessionConfiguration.background(withIdentifier: bundleIdentifier + ".background")
    )
  }()

Then I am using it like this:

  self.backgroundManager.download(fileUrl, to: destination)
    .downloadProgress { progress in
      //print("Download Progress: \(progress.fractionCompleted)")
    }
    .response(completionHandler: result)

It's in downloadPhoto method and I am calling it:

for item in items {
      self.downloadPhoto(item: item, isThumbnail: true, shouldReloadData: false, indexPath: nil)
      self.downloadPhoto(item: item, isThumbnail: false, shouldReloadData: false, indexPath: nil)
}

Then I could add call for file download and video download and other. But all this requests have same priority and I would like to download thumbnails first (because that's what user see at first) then full size images and after all images are downloaded then files and videos. But all must be in queue because if user starts app and then set it to background and left it for several hours all must be downloaded. Is this possible? And how can I do this?

I was looking at alamofire that it has component library AlamofireImage which has priority based downloading but images are just part of files which I want to prioritize. Thanks for help

Humus answered 1/12, 2016 at 14:9 Comment(1)
just a note: as an user i would not like that the app in background use all mey cellphone data plan for downloading all that stuff. did you plan to inform the user about this download? or only in wifi mode?Xanthein
J
4

Have a look at TWRDDownloadManager. It uses NSURLSessionDownloadTask and also supports background modes.

What you need to do is:

1. Set HTTPMaximumConnectionsPerHost to 1 to be sure that download happen serially:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.timeoutIntervalForRequest = 30.0;
configuration.HTTPMaximumConnectionsPerHost = 1; // Note this

2. Following is the method which iterate for loop and download media one by one:

-(void)downloadDocuments
{
    for(int i=0; i<[arrDownloadList count]; i++)
    {
        Downloads *download = [arrDownloadList objectAtIndex:i];
        NSString *fileURL = download.documentURL;

        [[TWRDownloadManager sharedManager] downloadFileForURL:fileURL 
                                                      withName:[fileURL lastPathComponent] 
                                              inDirectoryNamed:kPATH_DOC_DIR_CACHE_DOCUMENTS
                                               completionBlock:^(BOOL completed)
         {
             if (completed) 
             {
                 /* To some task like database download flag updation or whatever you wanr */

                 downloadIndex++;

                 if(downloadIndex < [arrDownloadList count]) {
                     [self updateDownloadingStatus];
                 }
                 else {
                     [self allDownloadCompletedWithStatus:TRUE];
                 }
             }

             else
             {
                 /* Cancel the download */
                 [[TWRDownloadManager sharedManager] cancelDownloadForUrl:fileURL];

                 downloadIndex++;

                 if(downloadIndex < [arrDownloadList count]) {
                     [self updateDownloadingStatus];
                 }
                 else {
                     [self allDownloadCompletedWithStatus:TRUE];
                 }
             }

         } enableBackgroundMode:YES];
    }
}

Don't forget to enable background mode: enableBackgroundMode:YES

3. Enable Background Modes in Xcode:

enter image description here

4. Add the following method to your AppDelegate:

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
    [TWRDownloadManager sharedManager].backgroundTransferCompletionHandler = completionHandler;   
}

If you do this, the downloading will occur serially and it will continue even if App is in background or user locks the device.

Please add comment in case of any question or help regarding this.

Jobholder answered 10/1, 2017 at 13:50 Comment(0)
M
3

I believe that iOS standard URLSessionDownloadTask will help you. It has property priority, which looks like you need.

Here is official documentation

Here is some tutorial

Misnomer answered 10/1, 2017 at 23:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.