Forked from toddhopkinson/BackgroundTransferSample.swift
Created
April 4, 2019 14:48
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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