Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 871
Libor Zapletal Avatar asked Dec 01 '16 14:12

Libor Zapletal


People also ask

How does HTTP file download work?

Hypertext Transfer Protocol (HTTP) downloads use the same protocol as browsing websites to send the file data. It is the most popular way to download files from the internet. All web browsers use this to download files directly.

How do web browsers download files?

Fetching files from the server Traditionally, the file to be downloaded is first requested from a server through a client — such as a user's web browser. The server then returns a response containing the content of the file and some instructional headers specifying how the client should download the file.


2 Answers

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.

like image 167
NSPratik Avatar answered Sep 24 '22 08:09

NSPratik


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

like image 38
Vitalii Gozhenko Avatar answered Sep 24 '22 08:09

Vitalii Gozhenko