I need to upload an mp4 video file from iPhone/iPad to a server, also in the background, so I read that is possible with URLSession.uploadTask(with: URLRequest, from
solution as of 2020 with native URLSession
to run background upload with uploadTask
and multipart/form-data
:
multipart/form-data
as it required for my NodeJS serverURLSession
:let config = URLSessionConfiguration.background(withIdentifier: "uniqueID")
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
// This line is important: here we use withStreamedRequest
let task = session.uploadTask(withStreamedRequest: request)
task.resume()
A little bit about my server side:
Hope this help
Sometimes it is easier for the server to read file from form-data. For instance, the flask framework can read file uploaded in the format of form-data easily by request.files. Alamofire provides an easy way to do this
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(FilePath, withName: FilePath.lastPathComponent)
}, to: url).responseJSON { response in
debugPrint(response)
}
In this way, the file will be uploaded in the format of form-data.
After some attempts, I saw the URLSession.uploadTask(with: URLRequest, fromFile: URL) method attaches the file as raw body to the request, so the problem was the server counterpart that was parsing form-data requests instead raw body requests.After I fixed the server side script, the upload works in background with this code:
var request = URLRequest(url: "my_url")
request.httpMethod = "POST"
request.setValue(file.lastPathComponent, forHTTPHeaderField: "filename")
let sessionConfig = URLSessionConfiguration.background(withIdentifier: "it.example.upload")
sessionConfig.isDiscretionary = false
sessionConfig.networkServiceType = .video
let session = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: OperationQueue.main)
let task = session.uploadTask(with: request, fromFile: file)
task.resume()