Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save enisinanaj/56fb215696768d7bd1bece050acff9b2 to your computer and use it in GitHub Desktop.
Save enisinanaj/56fb215696768d7bd1bece050acff9b2 to your computer and use it in GitHub Desktop.
Upload Very Large Files In Background on iOS - Alamofire.upload multipart in background
// You have a very very large video file you need to upload to a server while your app is backgrounded.
// Solve by using URLSession background functionality. I will here use Alamofire to enable multipart upload.
class Networking {
static let sharedInstance = Networking()
public var sessionManager: Alamofire.SessionManager // most of your web service clients will call through sessionManager
public var backgroundSessionManager: Alamofire.SessionManager // your web services you intend to keep running when the system backgrounds your app will use this
private init() {
self.sessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.default)
self.backgroundSessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.background(withIdentifier: "com.lava.app.backgroundtransfer"))
}
}
class VideoUploadClient {
class func upload(videoURL: URL, success: (() -> Void)?, failure: ((Error) -> Void)?) {
Networking.sharedInstance.backgroundSessionManager.upload(multipartFormData: { (multipartData) in
// multipart setup
}, usingThreshold: SessionManager.multipartFormDataEncodingMemoryThreshold, to: url, method: .post, headers: ["Content-Type":"multipart/form-data"], encodingCompletion: { encodingResult in
// transmission closure
switch (encodingResult) {
// encodingResult success
case .success(let request, let streamingFromDisk, let streamFileURL):
// upload progress closure
request.uploadProgress(closure: { (progress) in
print("upload progress: \(progress.fractionCompleted)")
// here you can send out to a delegate or via notifications the upload progress to interested parties
})
// response handler
request.responseJSON(completionHandler: { response in
switch response.result {
case .success(let jsonData):
// do any parsing on your request's response if needed
success?()
case .failure(let error):
failure?(error)
}
})
// encodingResult failure
case .failure(let error):
failure?(error)
} // end encodingresult switch
}) // end upload call
}
} // end VideoUploadClient class
// meanwhile, from a call site somewhere
// ...
class UploadViewController {
// ...
// assume defined and ready
let localVideoURL = URL(someLocalFile)! // force unwrap just for brevity of example, don't do this in real life.
let successClosure: (() -> Void)? = {
print("succeeded :)")
}
let failClosure: ((Error) -> Void)? = {
print("failed :(")
}
func uploadButtonAction() {
VideoUploadClient.upload(localVideoURL, successClosure, failClosure)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment