0

I am implementing a multiple images download for my app (at least 4000+ images), to do this, i have been looking for a best practice for a while, the solution that i found is to use a NSURLSession with a background configuration, i did all that i found in examples, but, sill not working in my real device.

I made a test showing a local notification when the downloads were completed, when i am in debuggin mode the notification is shown perfectly, but when i unplug the device, the notification doesnt work.

Note: The memory ussage in debug is low, but the energy impact is very high, it is possible that the operative system kill the process to prevent batery loss?

Any ideas?

Edison Mejia
  • 31
  • 1
  • 4
  • Hi Rob, i understand you about best practice, unfortunately i have to download all these images in a row, because my app is a virtual catalog, and the user could do that. About the configuration i have something like this: `NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example"]; sessionConfiguration.HTTPMaximumConnectionsPerHost = 1; self.backgroundSession = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];` – Edison Mejia Dec 19 '16 at 18:24
  • Are you instantiating that `NSURLSession` while app is in foreground? I ask because this sounds `discretionary`, which, [as the docs](https://developer.apple.com/reference/foundation/nsurlsessionconfiguration/1411552-discretionary?language=objc) say, "The session object applies the value of this [`discretionary`] property only to transfers that your app starts while it is in the foreground. For transfers started while your app is in the background, the system always starts transfers at its discretion—in other words, the system assumes this property is YES and ignores any value you specified." – Rob Dec 19 '16 at 18:43
  • Lazy loading is useless in my app because the customer's requirement is that the application should work in offline mode, they want to download all the images at once, so after they could see the entire catalog without internet connection. – Edison Mejia Dec 19 '16 at 18:51
  • Have you implemented `handleEventsForBackgroundURLSession` in your app delegate? While debugging, your app is artificially kept alive. In real-world scenarios, you have to handle the reinstantiation of your background session when the app receives `handleEventsForBackgroundURLSession` and then call that completion handler when you're done handling all of those events. – Rob Dec 19 '16 at 18:51
  • I am instantiating the `NSURLSession` while app is in foreground, and then i put the app in background mode, i dont understand much about discretionary. – Edison Mejia Dec 19 '16 at 18:53
  • Thank you so much, i will try with handleEventsForBackgroundURLSession, and see if works :) – Edison Mejia Dec 19 '16 at 18:57
  • Very good. You'll want to get rid of `sessionConfiguration.HTTPMaximumConnectionsPerHost = 1;`, too. – Rob Dec 19 '16 at 18:59
  • One final observation: I want to make sure that you're merely suspending the app (i.e. pressing the home button), not killing the app (i.e. double tapping on home button and swiping up on the app). If you kill an app, it terminates background sessions. If you let it merely suspend (and perhaps later be jettisoned due to memory pressure), then your background sessions will proceed. – Rob Dec 19 '16 at 19:03
  • Of course, i am not killing the app (just tapping the home button and wait) – Edison Mejia Dec 19 '16 at 19:19

1 Answers1

0

For downloading images, I'd highly recommend SDWebImage. It's a very robust library that's been maintained for a long time and should be able to do everything you're looking for.

Even just for downloading images, it's as easy as this:

SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
[downloader downloadImageWithURL:[NSURL URLWithString:@"https://www.example.com/example.png/"]
                         options:0
                        progress:^(NSInteger receivedSize, NSInteger expectedSize) {
                            NSLog(@"Image download %.02f%% complete.", (CGFloat)receivedSize/(CGFloat)expectedSize * 100);
                        }
                       completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
                           if(image && finished) {
                               NSLog(@"The image has finished downloading!");

                               //Perform your image related code here
                           }
                       }];

You could use it along with background tasks for your use case.

Community
  • 1
  • 1
Edwin Finch
  • 913
  • 3
  • 10
  • 24
  • Thank you, but i need to download 4000+ images in a row, first i am starting a background session when my app is in foreground, but when i put the app in background, the app is killing or pausing my background session – Edison Mejia Dec 20 '16 at 19:50