Replies: 21 comments 11 replies
-
@jshier Any idea how you want to see this implemented or any plan for how to make room for it? It's a frustrating feature gap. |
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
Hey @jshier ! Hope you are well. We are using AFNetworking in our project for 7 years - but the time has come and after 8 months we are almost done with complete Networking rewrite to Alamofire. The only reason why we have to keep AFNetworking in the project right now is This ticket is open for more than 3.5 years and I know you are (were) actively working on AFNetworking as well so you know the codebase too. Is there any blocker from porting the implementation to Swift from AFNetworking, or are you planning something else here, or what exactly is the plan with this? Is this still on roadmap? If so, can we as a community help somehow? Thanks, Jakub |
Beta Was this translation helpful? Give feedback.
-
@Kaspik AFNetworking and Alamofire have a completely different architectures so it's not possible to share a design. Feel free to implement some sort of background support if you want (though you should probably start with a design proposal we can review before you invest too much time) but background session support just isn't a high priority right now. Actual background sessions are so limited and their use case so narrow (large uploads and downloads) that it's not really some most Alamofire users need, and most of those who think they do really don't. And like I said in the initial issue, real background support would require a completely different approach to many of Alamofire's core APIs, and many others just wouldn't work at all. |
Beta Was this translation helpful? Give feedback.
-
Any update on Alamofire support for URLSessionConfiguration.background |
Beta Was this translation helpful? Give feedback.
-
No. Properly supporting background |
Beta Was this translation helpful? Give feedback.
-
Background support is a critical feature for our organization, as well as several others. For now, I'll go back to AFNetworking, although that seems to no longer be supported as of a year and a half ago. I'd really like to use a library with more modern API support without having to reinvent those wheels. Please let me know how I can help support you and the community on this. |
Beta Was this translation helpful? Give feedback.
-
@rmdvector One thing that would help would be to describe how you currently use background sessions, so we can get a better idea of what Alamofire needs to do and how it can help when it builds this feature. And while AFNetworking technically supports background sessions I don't believe it supports them properly, so there are likely quite a few things that are broken there. For Alamofire to support it we'd want to tailor the exposed APIs to only what background sessions support. For instance, background sessions have no support for customizing caching or redirects, so we'd want to make sure we don't expose those APIs. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the quick reply @jshier ! We are automating bills of lading for the shipping industry. One of our core features is workflow, in which a truck driver communicates with a warehouse shipping office to coordinate the pickup or delivery. What ends up happening is drivers will upload the bill of lading (an image file, along with some form data) as a POST upload (and yeah I learned the hard way this week that everything has to be a file upload for background sessions to even work). Some drivers then background or close the app, which kills the upload in progress, so the data isn't ready when they arrive at the warehouse. Glad to go into more details here or offline. |
Beta Was this translation helpful? Give feedback.
-
You may be able to get away with taking a background assertion to get more background time rather than using a real background session, depending on how big your images are. But you're right, this would be better as a discussion. Let me activate that feature and we can continue there. |
Beta Was this translation helpful? Give feedback.
-
Have similar use case - teachers can select up to 10 media files and send them as a post to the parents / students / whole school. Because school WiFi is not always the best quality, a lot of them have to go to teach before the upload is done thus background the app or lock the phone - but we should still try to deliver everything to students and upload correctly on background. |
Beta Was this translation helpful? Give feedback.
-
Welcome to GitHub Discussions! I've converted this issue into a discussion so we can discuss the issues surrounding |
Beta Was this translation helpful? Give feedback.
-
Let me put here what we currently have with AFNetworking support (only thing we have AFNetworking for, we are fully on Alamofire otherwise).
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
CDKUploadController.shared.backgroundCompletionHandler = completionHandler
}
final class CDKUploadController: NSObject {
// MARK: - Singleton
static let shared = CDKUploadController()
// MARK: - Properties
let backgroundSessionManager: AFURLSessionManager
var backgroundCompletionHandler: (() -> Void)?
// MARK: - Initializer
override init() {
let sessionConfiguration = URLSessionConfiguration.background(withIdentifier: "com.ClassDojo.backgroundMediaUpload")
sessionConfiguration.sessionSendsLaunchEvents = true
backgroundSessionManager = AFURLSessionManager(sessionConfiguration: sessionConfiguration)
super.init()
backgroundSessionManager.setDidFinishEventsForBackgroundURLSessionBlock { _ in
var backgroundTask: UIBackgroundTaskIdentifier = .invalid
backgroundTask = UIApplication.shared.beginBackgroundTask(expirationHandler: { [weak self] in
self?.backgroundCompletionHandler?()
self?.backgroundCompletionHandler = nil
UIApplication.shared.endBackgroundTask(backgroundTask)
backgroundTask = .invalid
})
}
}
/// Mark the start of a task that should continue if the app enters the background.
/// - Parameter expirationHandler: A handler to be called shortly before the app’s remaining background time reaches 0. Use this handler to clean up and mark the end of the background task. Failure to end the task explicitly will result in the termination of the app. The system calls the handler synchronously on the main thread, blocking the app’s suspension momentarily.
/// - Returns: The backgroundTaskIdentifier value used to call endBackgroundTask
@objc public func beginBackgroundTask(expirationHandler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
return UIApplication.shared.beginBackgroundTask(expirationHandler: expirationHandler)
}
@objc public func endBackgroundTask(identifier: UIBackgroundTaskIdentifier) {
guard identifier != .invalid else {
return
}
UIApplication.shared.endBackgroundTask(identifier)
}
func upload(attachments: [CDKAttachment]) -> Promise<CDKUploadResponse> {
return Promise { seal in
var latestKnownProgress: Double = 0.0
let childProgress = Progress(totalUnitCount: Int64(100))
parentProgress.totalUnitCount += childProgress.totalUnitCount
parentProgress.addChild(childProgress, withPendingUnitCount: childProgress.totalUnitCount)
let uploadTask = self.backgroundSessionManager.uploadTask(with: request, fromFile: localURL, progress: { progress in
DispatchQueue.main.async {
childProgress.completedUnitCount = Int64(progress.fractionCompleted * Double(childProgress.totalUnitCount))
latestKnownProgress = progress.fractionCompleted * 100.0
}
}, completionHandler: { _, _, error in
if let error = error {
seal.reject(error: error)
} else {
seal.fulfill(validResponseObject)
}
})
uploadTask.resume()
}.catch { error in
seal.reject(error)
}
}
} Then extension CDKMessage {
func createOnAPI() -> Promise<Void> {
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
backgroundTaskID = CDKUploadController.shared.beginBackgroundTask(expirationHandler: {
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
})
return CDKUploadController.shared.upload(attachments: attachments)
.then { () -> Promise<[String: Any]?> in
return API.JSONRequest(resource: Resource.Common.postMessage(params: [:]))
}
.map { response -> [String: Any] in
return try Networking.unwrap(responseObject: response)
}
.then { response -> Promise<Void> in
return self.processAndSave(responseObject: response)
}
.then { () -> Promise<Void> in
CDKUploadController.shared.endBackgroundTask(identifier: backgroundTaskID)
backgroundTaskID = .invalid
return Promise<Void>.value(())
}
.recover { error in
CDKUploadController.shared.endBackgroundTask(identifier: backgroundTaskID)
backgroundTaskID = .invalid
throw error
}
}
} I guess we are not doing anything special here, but also we were not able to come up with something easier than this too much sophisticated system. The |
Beta Was this translation helpful? Give feedback.
-
@Kaspik It's hard to tell what part of that code requires Part of the difficulty here is that's it's essentially impossible to test the true background mode, so handling these sorts of expiration edge cases will be difficult if not impossible. General support for |
Beta Was this translation helpful? Give feedback.
-
In our case, using a background task to manage the upload might help, but when a truck driver is on the open road they almost certainly won't have wifi, and may not have the best cellular data, so the 30 second limit probably won't be enough to upload the image (usually less than a megabyte, typically 500k or so, it's cropped and uploaded as .heic) plus the associated metadata, about 2-10k of JSON text. To make things more exciting, there are usually a couple of JSON metadata uploads, and there may be multiple workflows in flight at the same time, e.g. a driver is dropping off a load and picking up the next load. |
Beta Was this translation helpful? Give feedback.
-
Any update on Alamofire support for URLSessionConfiguration.background, |
Beta Was this translation helpful? Give feedback.
-
@jshier So, Is there any backgroundFetch support for this scenerio rather than downloading and uploading task? |
Beta Was this translation helpful? Give feedback.
-
One thing people can try if they'd like to see how Alamofire currently handles background sessions is to fork the repo and remove the assertion I added which prevents the use with background configurations. After that you'll be able to explore what may be missing or broken when used in the background or launched from a completed background request. |
Beta Was this translation helpful? Give feedback.
-
Do we have any timeline for this feature? 👀 |
Beta Was this translation helpful? Give feedback.
-
I need to download a long video. It's not friendly to the user if I keep them in foreground. So I want to download the video in the background and notify the user when the video is downloaded. |
Beta Was this translation helpful? Give feedback.
-
@jshier You mentioned earlier that "You may be able to get away with taking a background assertion to get more background time rather than using a real background session, depending on how big your images are." Can you explain what you mean by taking a background assertion? If you have a code example that would greatly help. In my case, I am uploading a video which can take 1-3 minutes to do. When the user begins uploading the video, they might background the app. I want the upload to continue to execute, and if it finishes in 1-3 minutes (or however much background time the OS gives me) that is fine, but if the OS runs out of time and stops the upload, that is fine with me too. I can just inform the user to re-try their upload with the app open. I just don't want the upload to stop as soon as the app is backgrounded, and give it more time to maybe finish. From what I understand, the OS decides on it's own how much time you get based on hardware, network, etc. Before I was using the background session in Alamofire 4, but if I can just extend the background execution time, that would work fine in my case. |
Beta Was this translation helpful? Give feedback.
-
While Alamofire technically supports background
URLSession
s, it currently cancels and invalidates the session whenSessionManager
s aredeinit
ed, which breaks background functionality. Alamofire should have real background support, which will likely require a completely new API model, as the closure based one currently used may not work well.Beta Was this translation helpful? Give feedback.
All reactions