Alamofire上传具有进度的大文件,并在应用重启时显示进度

时间:2018-08-20 12:56:18

标签: ios swift alamofire

我已经按照以下步骤设置了项目。

  1. 我启用了外部附件通讯和后台获取
  2. AppDelegate:
   
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        API.sharedInstance.backgroundCompletionHandler = completionHandler
    }
  1. 这是API.swift类,它用于处理所有api调用
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 个答案:

答案 0 :(得分:1)

要在完成时运行操作,您需要覆盖会话的委托sessionDidFinishEventsForBackgroundURLSession:(((URLSession)-> Void)? Alamofire doc

对于每次上传的进度,我仍在尝试重新连接委托的方法,但到目前为止没有成功。 我们一定在做错事