2

I have been using NSURLSession to do background uploading to AWS S3. Something like this:

NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@“some.identifier"];
NSURLSession* session = [NSURLSession sessionWithConfiguration:configuration delegate:someDelegate delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionUploadTask* task = [session uploadTaskWithRequest:request fromFile:[NSURL fileURLWithPath:httpBody]];
[task resume];

In someDelegate, I have implemented didSendBodyData, didCompleteWithError and handleEventsForBackgroundURLSession.

I have three questions:

  1. I have noticed that if I close the app while uploading is in progress, transfer will continue and successfully finish. Is handleEventsForBackgroundURLSession called when the transfer is finished while the app is closed?
  2. Assuming that the answer to the first question is yes, how can I delete httpBody in handleEventsForBackgroundURLSession? This is a temporary file that is not needed once transfer is complete.
  3. I would appreciate it if someone explained, in detail, how background transfer works in iOS. That is when memory is created, which callbacks are called at which states and how the app is woken up once the transfer is completed. Thanks.
Rob
  • 415,655
  • 72
  • 787
  • 1,044
siavashk
  • 436
  • 7
  • 24
  • Please google before you come here at SO. Apple has already given a good explanation of the background processes. https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html – Harjot Singh Oct 27 '17 at 19:02
  • I have already read Apple’s description. I did not find it adequate, where does it say how memory is allocated/deallocated? – siavashk Oct 27 '17 at 19:08
  • Memory is handled by OS and By ARC automatically. – Harjot Singh Oct 27 '17 at 19:10
  • #1 Why didn't you test it? – Amin Negm-Awad Oct 27 '17 at 19:24
  • I am trying to test it, but when I close the app, the debugger is dettached so I cannot place a breakpoint. – siavashk Oct 27 '17 at 19:25
  • The debugger doesn't detach when the app goes to the background. Are you saying you're killing the app? – jscs Oct 27 '17 at 19:48
  • Yes, when I kill the app. Double tap on home button and close. – siavashk Oct 27 '17 at 19:49
  • 2
    When you kill the app, all background transfers **stop**. – dgatwood Oct 27 '17 at 20:01
  • OK, I might be making a mistake then. But before I closed the app, I put a break point in `didSendBodyData`, so that transfer would be paused and then I closed the app. Would not this mean that transfer continues while the app is killed? What is wrong with my conclusion? Sorry if this is trivial. – siavashk Oct 27 '17 at 20:06
  • Transfer cannot be continued when you will kill the app, as the app is not in memory anymore. – Harjot Singh Oct 27 '17 at 20:11
  • 2
    @HarjotSingh you are wrong. From Apple’s documentation: If your app is terminated while transfers are ongoing, the system continues the transfers in the background and launches your app (as appropriate) when the transfers finish or when one or more tasks need your app’s attention. – siavashk Oct 27 '17 at 20:21
  • @siavashk I am not wrong, it is the kind of alert that os throws while your trying to kill the app when the transfers are ongoing and when you have killed the app, the transfers stop. – Harjot Singh Oct 27 '17 at 20:23
  • I don’t know. To me ``If your app is terminated while transfers are ongoing, the system continues the transfers in the background’’, is the exact opposite of what you are saying. – siavashk Oct 27 '17 at 20:38
  • 1
    @siavashk https://stackoverflow.com/a/28867137/8810022 check here for the clear view of the transfers in background – Harjot Singh Oct 27 '17 at 21:23
  • 1
    The description is misleading in the ``Background Execution'' then. Thanks. – siavashk Oct 27 '17 at 21:30
  • 1
    Thank you @Rob. This perfectly answers my question. If you write the comments as an answer, I will accept it. – siavashk Oct 27 '17 at 21:35
  • 1
    @Rob thank you! I will bring up `OSLog` with our CTO. – siavashk Oct 27 '17 at 21:42

1 Answers1

5

When the app delegate's handleEventsForBackgroundURLSession is called, you should:


A few additional notes:

  • There seems to be some confusion about what happens when an app is terminated.

    If the app is terminated in the course of its normal lifecycle, the URLSession daemon will keep the background requests going, finishing your uploads, and then wake up your app when it's done.

    But manually force-quitting the app (e.g., double tapping on home button, swiping up on the app to force it to quit) is a completely different thing (effectively, the user is saying "stop this app and everything associated with it"). That will stop background sessions. So, yes, background sessions will continue after the app is terminated, but, no, not if the user force-quit the app.

  • You talk about setting breakpoints and observing this in Xcode. You should be aware that the process of being attached to Xcode will interfere with the normal app life cycle (it keeps it running in background, preventing it from being suspended or, during the normal course of events, terminating).

    But when testing background session related code, it's critical to be test the handleEventsForBackgroundURLSession workflow when your app was terminated, so to that end, I'd suggest not using Xcode debugger when testing this dimension of background sessions.

    I use the new OSLog unified logging system, because the macOS Console can watch what is logged by the app, while not having Xcode running at all. Then I can write code that starts some download or upload, terminates app and then watch the logging statements I have inserted in order to observe the restarting of the app in background via the macOS console. See Unified Logging and Activity Tracing video for a tutorial of how to watch iOS logs from the macOS Console.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Rob, perhaps I should post a new question for this, but no matter how I scour SO and web in general I've not encountered any example implementations of handleEventsForBackgroundURLSession that show how to recreate the session ("instantiate your background NSURLSession") as you put it. They simply save the completion handler, even though the docs on this method describe a scenario where the app must recreate a session with the supplied identifier. Is a singleton called for that is shared by both the app delegate and the class that originally launched the task? – Alyoshak Nov 22 '17 at 03:43
  • 1
    @Alyoshak - I'm surprised you haven't found examples, because it's an absolutely essential part of any background session. I would have thought it would be included in any complete example of background sessions for iOS. – Rob Nov 22 '17 at 05:44
  • @Alyoshak - Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/159615/discussion-between-rob-and-alyoshak). – Rob Nov 22 '17 at 19:52