swifturlsessionnsurlsessionuploadtask

How to handle URLSessiosn UploadTask ResumeData when delegate method got fired?


I was implementing an upload task using URLSession Uploadtask with the below code:

         lazy var urlSession = URLSession(
           configuration: .background(withIdentifier: "com.test.xxxxx"),
           delegate: self,
           delegateQueue: .main
         )
         var uploadTask = URLSessionUploadTask()

          
         /// Calling uploadtask using 'fileURL' of the asset
         var request = URLRequest(url: URL(string: url)!)
         request.httpMethod = "PUT"
         uploadTask = urlSession.uploadTask(with: request, fromFile: fileURL)
         uploadTask.resume()

And uploading works as expected, my concern is if I want to use resume data whenever user removes the app from multitask window or any error happens in between uploading a file, how can i achieve it using below delegate method, this delegate method is firing for me, but we don't have any methods to use resume data like func downloadTask(withResumeData resumeData: Data) -> URLSessionDownloadTask for upload task or is it not possible for upload task, please guide me on this. Thank you.

 func urlSession(_: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let error = error {
            // Here comes when background upload failed with errors
            // Such as app closed from the tray ,switched off ,crash occured, etc.
            // Then, handle with resumeData
            os_log("Download error: %@", type: .error, String(describing: error))
        } else {
            // Here comes when background upload completed with no error
            os_log("Task finished: %@", type: .info, task)
        }
    }

Edit: I can't see anything related to resume data for upload task in Apple doc also.


Solution

  • The only reason download resuming is possible is because you are downloading a file from a known path on the server, so your browser can ask the server to start sending at byte #n if that file hasn't changed since ETAG x.

    In general, most uploads to a server aren't just writing to a file on disk at a specific path. They're writing data to some arbitrary temporary file, kicking off some server-side bookkeeping to tie that temporary file to a user account, etc.

    When an upload stops partway through, most server-side software discards any previously uploaded data. Thus, resuming an upload typically isn't possible (ignoring special cases like WebDAV), because the previous data ceases to exist as soon as the connection drops.

    Any support for resumable uploads would require writing custom server-side CGI that:

    and does all of this in a manner that is compatible with whatever custom software you write on the client side. In other words, this really isn't a problem that can be solved in a general way by the operating system.

    I suspect that there are server-side tools that are designed to support these use cases, though I can't name any of them off the top of my head, but either way, it is out-of-scope for the NSURLSession API.

    If your concern is about downloading some large resource at the end of an upload, however, the way you would typically solve that is by having your upload response be a redirect to a new location.

    Then, you can intercept the redirect attempt, and create a new task with that request, which you can retry (it should ideally be idempotent) or resume or whatever as needed.