Alamofire 上传带有进度的大文件并在应用重启时显示进度
Posted
技术标签:
【中文标题】Alamofire 上传带有进度的大文件并在应用重启时显示进度【英文标题】:Alamofire uploading large files with progress and show progress on app restart 【发布时间】:2018-08-20 12:56:17 【问题描述】:我已通过以下步骤设置项目。
-
我已启用外部附件通信和后台获取
AppDelegate:
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void)
API.sharedInstance.backgroundCompletionHandler = completionHandler
-
这里是处理所有 api 调用的 API.swift 类
public class API: NSObject
var sessionManager: SessionManager
var delegate: SessionDelegate
public var backgroundSessionManager: Alamofire.SessionManager
var backgroundCompletionHandler: (() -> Void)?
get
return backgroundSessionManager.backgroundCompletionHandler
set
backgroundSessionManager.backgroundCompletionHandler = newValue
/// access a shared instance of an API manager
public class var sharedInstance: API
struct Singleton
static let instance = API()
return Singleton.instance
public required override init()
let configuration = URLSessionConfiguration.default
self.sessionManager = SessionManager(configuration: configuration)
let identifier = "com.appname.backgroundtransfer"
self.backgroundSessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.background(withIdentifier: identifier))
self.sessionManager.adapter = AccessTokenAdapter()
delegate = self.backgroundSessionManager.delegate
func authHeaderWithToken() -> [String : String]
return [Constants.HeaderKeys.Authorization : "Bearer " + (AppManager.sharedInstance.accessToken ?? "")]
func uploadFilesToServer(parameters: [String : Any], image: UIImage?, audio: Data?, video: Data?, uploadItem: Upload, progressHandle: @escaping ProgressHandler, success: @escaping SuccessJsonClosure, failed: @escaping NetworkError)
let URL = Constants.BASE_URL + "api_uploadFiles"
let headers: HTTPHeaders = [
Constants.HeaderKeys.Authorization : "Bearer " + (AppManager.sharedInstance.accessToken ?? ""),
"Content-type": "multipart/form-data"
]
self.backgroundSessionManager.upload(multipartFormData: (multipartData) in
// multipart setup
if let img = image
multipartData.append(UIImageJPEGRepresentation(img, 1.0)!, withName: "file", fileName: "\(uploadItem.fileName!)", mimeType: "image/jpeg")
if let vid = video
multipartData.append(vid, withName: "file", fileName: "\(uploadItem.fileName!)", mimeType: "video/mov")
if let aud = audio
multipartData.append(aud, withName: "file", fileName: "\(uploadItem.fileName!)", mimeType: "audio/mov")
for (key, value) in parameters
multipartData.append("\(value)".data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!, withName: key)
, to: URL, method: .post, headers: headers, 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)")
progressHandle(progress)
)
// response handler
request.responseJSON(completionHandler: response in
switch response.result
case .success(let jsonData):
// do any parsing on your request's response if needed
let json = try! JSON(data: response.data!)
let isOK = json["success"].boolValue
if isOK
success(true, json)
else
failed(nil, json)
case .failure(let error):
failed(error, nil)
)
// encodingResult failure
case .failure(let error):
failed(error, nil)
// end encodingresult switch
)
如果应用程序没有被杀死,文件会成功上传到服务器。但如果我在上传过程中终止应用程序,我将无法获得进度状态。当应用程序重新启动(杀死并打开)时,完成块不会被执行。 uploadFilesToServer 函数多次调用(例如:5 个视频上传和 5 个调用)。当应用程序重新启动时,我需要跟踪每次上传的进度。我们如何跟踪正在进行的请求?以及我们如何上传大文件并为每个请求运行完成调用。
在这里我将视频保存到文档目录并使用 url 传递数据
【问题讨论】:
【参考方案1】:要在完成时运行操作,您需要覆盖会话的委托 sessionDidFinishEventsForBackgroundURLSession: ((URLSession) -> Void)? Alamofire doc
对于每次上传的进度,我仍在尝试寻找重新附加代理的方法,但到目前为止还没有成功。 我们一定是做错了什么
【讨论】:
以上是关于Alamofire 上传带有进度的大文件并在应用重启时显示进度的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Alamofire 4.0 中添加带有上传进度百分比的标签的进度条
通过 API 将带有 Alamofire 的 STL 文件上传到 Octoprint