Curiosity
Curiosity

Reputation: 264

How do you extend an iOS app's background execution time when continuing an upload operation?

I'd like a user's upload operation that's started in the foreground to continue when they leave the app. Apple's article Extending Your App's Background Execution Time has the following code listing

func sendDataToServer( data : NSData ) {
   // Perform the task on a background queue.
   DispatchQueue.global().async {
   // Request the task assertion and save the ID.
   self.backgroundTaskID = UIApplication.shared.
             beginBackgroundTask (withName: "Finish Network Tasks") {
     // End the task if time expires.
     UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
     self.backgroundTaskID = UIBackgroundTaskInvalid
   }
        
   // Send the data synchronously.
   self.sendAppDataToServer( data: data)
        
   // End the task assertion.
   UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
   self.backgroundTaskID = UIBackgroundTaskInvalid
   }
}

The call to self.sendAppDataToServer( data: data) is unclear. Is this where the upload operation would go, wrapped in Dispatch.global().sync { }?

Upvotes: 2

Views: 1240

Answers (1)

Rob
Rob

Reputation: 437682

You have stumbled across a less-than-stellar code sample in Apple’s documentation.

  • First, if you perform a synchronous network request, you definitely should dispatch it to a background queue. If you don't, you risk having the watchdog process kill your app. But you shouldn’t dispatch the network request synchronously to the global queue, but rather asynchronously, or else you just end up with the same problem, namely blocking the main thread.

  • That having been said, one really should never perform network requests synchronously. You should perform them asynchronously and end the background task in the completion handler.

  • In that example, they use NSData, which we don’t use anymore.

  • Also UIBackgroundTaskInvalid doesn’t exist anymore. It is now UIBackgroundTaskIdentifier.invalid.

  • In Apple’s defense, the point of this code sample is the background task, not the network code. They really didn’t want to get into the weeds of the implementation of this network code and were trying to keep it simple. That having been said, it really is a horrible and outdated code example.

See this answer for a better example of how one might use background tasks. Also, if the upload might take more than 30 seconds, we wouldn’t use the background task at all, but a proper (but more complicated) background URLSession. (See Downloading files in the background. Upload tasks follow the same basic pattern outlined there, though make sure to upload from a file, not a Data.)

Upvotes: 4

Related Questions