Completion handler blocks are not supported in background sessions.
TheTekton opened this issue · comments
Using SessionConfiguration.Background and a custom delegate with a POST request ends up with the error "Completion handler blocks are not supported in background sessions." I was thinking about working around that by creating a SessionUploadTask class based on SessionDataTask, using session.uploadTaskWithRequest (http://stackoverflow.com/a/23738200), to support background uploads. Doing so seems like it will be fairly straight forward, as long as the upload body tmp file is dealt with correctly (and probably will need to store the task identifier).
Is this kind of usage (background upload using uploadTaskWithRequest and a body file) something that Malibu might support eventually?
@TheTekton! Yes, it should be possible and we're thinking about upload tasks support in next versions.
Cool, I hacked together a workaround I can use, in the meantime. TheTekton@56668f7 Since I'm using Malibu in a react-native module, I had to make some things public so they could be exported to ObjC or a local implementation could be used. In any case, the highlights of getting background upload going were:
- Add a 'Background' mode to Malibu *1 *2 *3
- Add an optional backgroundTask closure to POST (probably not the best way, but was quick and easy) *1
The POST call (uploadMessage is just an in-house config object):
public func uploadFile() {
ride = networkingBridge!.POST(MyImageCreateRequest(requestUploadMessage: uploadMessage!), backgroundTask: { (session: NSURLSession, URLRequest: NSURLRequest, taskRide: Ride) -> TaskRunning in
return SessionUploadTask (session: session, URLRequest: URLRequest, ride: taskRide, transferUpload: self)
})
}
The SessionUploadTask (MyBackgroundTransferUploadModule is my bridge object which also has the required delegates):
import Foundation
import When
import Malibu
class SessionUploadTask: TaskRunning {
var transferUpload: MyBackgroundTransferUploadModule
var session: NSURLSession
var URLRequest: NSURLRequest
var ride: Ride
// MARK: - Initialization
init(session: NSURLSession, URLRequest: NSURLRequest, ride: Ride, transferUpload: MyBackgroundTransferUploadModule) {
self.transferUpload = transferUpload
self.session = session
self.URLRequest = URLRequest
self.ride = ride
}
// MARK: - NetworkTaskRunning
func run() {
let uploadMessage = self.transferUpload.uploadMessage
let task = session.uploadTaskWithRequest(URLRequest, fromFile: NSURL(fileURLWithPath: uploadMessage!.tmpFilePath))
// uploadFileStarted() is signaling that background upload is initialized
uploadMessage?.taskId = String(format: "%d", task.taskIdentifier)
self.transferUpload.uploadFileStarted (uploadMessage!)
task.resume()
ride.task = task
}
}
I'm new to Swift, so I don't expect this would be considered that great. 😝 In any case, I thought I'd share in case it'd help at all.
Malibu
supports upload requests since https://github.com/hyperoslo/Malibu/releases/tag/5.0.0, so I think we can close this one.