vadymmarkov / Malibu

:surfer: Malibu is a networking library built on promises

Home Page:https://vadymmarkov.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

  1. Add a 'Background' mode to Malibu *1 *2 *3
  2. 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.