Alamofire network calls not being run in background thread
I was wrong about Alamofire running on a background thread by default. It actually runs on the main queue by default. I've opened an issue on Alamofire's Github page and it's been solved here: https://github.com/Alamofire/Alamofire/issues/1922
The correct way to solve my problem was to specify what kind of queue I want my request to be run on using the "queue" parameter on the .responseJSON method (
.responseJSON(queue: queue) { response in
...
}
)
This is the entire, corrected version of my code:
let productsEndPoint: String = "http://api.test.com/Products?username=testuser"
let queue = DispatchQueue(label: "com.test.api", qos: .background, attributes: .concurrent)
Alamofire.request(productsEndPoint, method: .get)
.responseJSON(queue: queue) { response in
// check for errors
guard response.result.error == nil else {
// got an error in getting the data, need to handle it
print("Inside error guard")
print(response.result.error!)
return
}
// make sure we got some JSON since that's what we expect
guard let json = response.result.value as? [String: Any] else {
print("didn't get products as JSON from API")
print("Error: \(response.result.error)")
return
}
// get and print the title
guard let products = json["products"] as? [[String: Any]] else {
print("Could not get products from JSON")
return
}
print(products)
}
Does Alamofire request actually run in the background thread?
Does Alamofire request actually run in the background thread
Yes,Alamofire tasks run in a background thread and dispatch their callbacks in main thread
Alamofire request gets stuck when entering background?
You can use background fetching to solve this problem. It can be done in the following way in Swift 3:
var backgroundTask: UIBackgroundTaskIdentifier? // global variable
backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "backgroundTask") {
// Cleanup code should be written here so that you won't see the loader
UIApplication.shared.endBackgroundTask(self.backgroundTask!)
self.backgroundTask = UIBackgroundTaskInvalid
}
Call your alamofire service after this line. In the completion handler, end the task using the below lines.
UIApplication.shared.endBackgroundTask(self.backgroundTask!)
self.backgroundTask = UIBackgroundTaskInvalid
Please note that the app has some background time (backgroundTimeRemaining
property) remaining before it enters the inactive state. You have to get your task done before that time. The handler is called shortly before the remaining background time reaches zero. Also, each call to the method beginBackgroundTask(withName:){}
must be balanced by a matching call to the endBackgroundTask:
method.
To make the code given above work, you need to adjust settings in your app. Go to "Targets" and click on "Capabilities" to make the following changes
After that, go to your info.plist file, and open it as Source to add the following code.
I hope this helps you. If you need more detailed information, these links might help
- https://developer.apple.com/reference/uikit/uiapplication/1623031-beginbackgroundtaskwithexpiratio
- https://developer.apple.com/reference/uikit/uiapplication/1622970-endbackgroundtask
Unable to make request with Alamofire upon receiving silent push while in background
After posting a local notification in the didReceiveRemoteNotification method I noticed that the notification was only posted when the app was started from Xcode. When starting the app from the device directly the app never posted the local notification. This leads me to believe that my app is not actually being woken up by the push notification. This therefore has nothing to do with Alamofire at this time so I will close this question.
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).
Related Topics
How Do People Deal with Iterating a Swift Struct Value-Type Property
Listing All Files in a Folder Recursively with Swift
How to Test Whether Generic Variable Is of Type Anyobject
What Does "Get" Mean in a Protocol's Property Declaration
Why How to Use Codable with a Project Language Version of Swift 3.3
Lazy Loading Properties in Swift
Swift Package Manager - Uikit Dependency
Add Switch in Uitableview Cell in Swift
Two Tables on One View in Swift
Invalid Update: Invalid Number of Items in Section 0
Parameters After Opening Bracket
Consume Swift Package for Multiple Targets and Platforms in a Project
Get the Last Character of a String Without Using Array
Are the #If Debug Statements Really Needed for Previews in Swiftui to Remove It in a Release Build