Hey, @audrey ! Thanks for your great video tutorials. I learned a lot from it!
I’m trying to build an app network layer which will allow upload different media (images/video/audio) to server in background while still responding to different user actions & updating server about them. Sometimes media could not be uploaded before one of user actions didn’t receive server response. And sometimes a specific user action has a priority over the other tasks and should be treated first as soon as it was added to queue. So I suppose kind of dependency exists between regular data tasks (such as QueryOperation) and upload tasks. Audrey, does it make sense to use operations for download/upload tasks as well? If the answer is yes, where backgroundSession should be declared? Does it should be in every UploadOperation having same session identifier? Thanks in advance.
In my coming-soon update to the URLSession tutorial, I rewrote the HalfTunes APIManager as two classes: QueryService and DownloadService, each with their own URLSession object. So you could organise your network tasks into services, each with its own configuration and session. You could configure priority for each service. Because you also need dependencies, you should subclass Operation or AsyncOperation to wrap the tasks as operations, and create your own OperationQueues. OperationQueue priorities are categorised differently from URLSessions, so you can adjust priorities here, too.
Note that you can set dependencies between operations that are in different operation queues, so use the operation queues to organise similar tasks.
take a look at the sample app from WWDC 2015 session 226 — it uses the WWDC app as an example, esp when the user tries to fave a session but isn’t yet logged into iCloud. The downloadable sample app is about Earthquakes but look at the comment in GroupOperation.swift, if authentication is a dependency for your app.
The Earthquakes app is pretty complex, but the idea is to organise your operations by function. I’ve attached slide 70 from WWDC 2016 Session 720: it’s about GCD but just substitute OperationQueue for DispatchQueue, to get the same effect:
wwdc2016_720_p70.zip (20.9 KB)
you could use the same background configuration for all uploads, but think carefully if an upload depends on a previous upload: if you start an upload in another upload’s completion/delegate, and that task completed in the background, the new upload task will be created as a discretionary task, so with very low priority.
good luck!
I believe setting the state to finished should happen irrespective of the presence / absence of error message.
Instead of
if let error = error {
self.errorMessage += "DataTask error: " + error.localizedDescription + "\n"
} else if let data = data,
let response = response as? HTTPURLResponse,
response.statusCode == 200,
let completion = self.completion {
self.updateSearchResults(data)
completion(self.tracks, self.errorMessage)
self.state = .finished
}
we should have
if let error = error {
self.errorMessage += "DataTask error: " + error.localizedDescription + "\n"
} else if let data = data,
let response = response as? HTTPURLResponse,
response.statusCode == 200,
let completion = self.completion {
self.updateSearchResults(data)
completion(self.tracks, self.errorMessage)
}
self.state = .finished