AlamoFire Download in Background Session
Update
Based on this amazing tutorial, I have put together an example project available on GitHub. It has an example for background session management.
According to Apple's URL Loading System Programming Guide:
In both iOS and OS X, when the user relaunches your app, your app
should immediately create background configuration objects with the
same identifiers as any sessions that had outstanding tasks when your
app was last running, then create a session for each of those
configuration objects. These new sessions are similarly automatically
reassociated with ongoing background activity.
So apparently by using the appropriate background session configuration instances, your downloads will never be "in flux".
I have also found this answer really helpful.
Original answer
From Alamofire's GitHub page:
Applications can create managers for background and ephemeral
sessions, as well as new managers that customize the default session
configuration, such as for default headers (HTTPAdditionalHeaders) or
timeout interval (timeoutIntervalForRequest).
By default, top level methods use a shared Manager
instance with default session configuration. You can however create a manager with background session configuration like so:
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.example.app.background")
let manager = Alamofire.Manager(configuration: configuration)
You can then make requests using this Manager
instance.
manager.startRequestsImmediately = true
let request = NSURLRequest(URL: NSURL(string: "your.url.here")!)
manager.request(request)
By looking at its implementation, it also has a property called backgroundCompletionHandler
, so you can add a completion block:
manager.backgroundCompletionHandler = {
// do something when the request has finished
}
Alamofire requests while device is sleeping
Yes, background sessions only permit upload and download tasks, not data tasks. They also only permit delegate-based requests, not completion handler-based requests. This answer outlines many of the considerations when doing this in conjunction with Alamofire.
But this begs the question as to whether you really want to use a background session at all. When your app is awaken for background fetch, if you’re able to finish you request within a reasonable amount of time (e.g. 30 seconds), you should probably consider a standard session, not a background session. It’s a lot simpler.
Do not conflate an app running in the “background” with a “background” URLSessionConfiguration
: They’re completely different patterns. Just because your app is running in the background, that doesn’t mean you have to use background URLSessionConfiguration
. If your app is running (whether in foreground or in the background), then a standard session is fine. You only need background session if you want it to continue after the app is suspended (or is terminated) and you’re willing to encumber yourself with all the extra overhead that background sessions entail.
Background sessions are not intended for requests performed while the app is running in the background. They’re intended for requests that will continue after your app is suspended (and even if it eventually is terminated in the course of its natural lifecycle). That means that background sessions are ideal for slow requests that cannot be completed in a reasonable amount of time, e.g., downloading video asset, downloading many large image assets or documents, etc.
But if you’re just performing a routine GET/POST request that will complete in a reasonable amount of time, consider not using background URLSessionConfiguration
, but just do normal request and call the background fetch completion handler when your request is done (i.e., in your network request’s completion handler).
Alamofire: How to download files sequentially
What you could do is call out to another function when a file completes downloading (i.e. totalBytesRead >= totalBytesExpectedToRead). In that function, pop the next item off your list and call the download function again with the new URL. You could make an array of all the URLs and when you need a new item, remove it from the array and pass it to the download function. Check if the array is empty and if it is, you know you are done downloading everything.
The reason you can't just use a loop as you have is that Alamofire requests are always asynchronous so after the request is made, control returns immediately and your program continues before any data is downloaded.
How to execute alamofire background upload request?
from Background Transfer Considerations
:
Only upload tasks from a file are supported (uploading from data objects or a stream will fail after the program exits).
that means it is limitation from NSURLSession - you need you upload from a file and then try to solve the other error with file
Update
appDeligate.log.debug("request was sended")
let tempZipFilePath = UtilDirectory.tempZipPath.tweak()
alamoFireManager.upload(tempZipFilePath,
to: deligate.url,
method: .post,
headers: headers)
Related Topics
How to Connect SQLite Database in iOS
Check If Username Already Exist'S:Swift, Firebase
Gamecenter iOS 9 Gamecenter Gklocalplayerlistener Methods Not Called
Xcode 7 Crash: [Nslocalizablestring Length] 30000
Objective-C Rabbitmq Client Not Publishing Messages to Queue
Uitableviewcell Textlabel Color Not Changing
Multiple Uicollectionview in One Controller
Delete and Update Data in Core Data in iOS
Ios9: Alternative to Uidevice.Currentdevice().Setvalue(...) to Force Orientation
How to Implement Tableview Inside Tableview Cell in Swift 3
Firebase Pod Install - Pod 'Firebase/Database' - Required a Higher Minimum Deployment Target
iOS 10 - App Crashes to Access Photo Library or Device Camera via Uiimagepickercontroller
Get User Swiping Direction in Uipageviewcontroller
Nspredicate for Array of Dictionaries