简体   繁体   中英

How to know the progress of upload in swift multipart request

I am using NSMutableURLRequest for multipart request in Swift iOS. How I can get the progress of the uploaded data on the server?

Currently I am using the following code:

let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
var request = NSMutableURLRequest(URL: url, cachePolicy: cachePolicy, timeoutInterval: 30000)
request.HTTPMethod = "POST"
request.setValue(NSUserDefaults.standardUserDefaults().objectForKey("access-token") as? String, forHTTPHeaderField: "Authorization")
// set Content-Type in HTTP header
let boundary = generateBoundaryString()

var body = NSMutableData.alloc()

request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.HTTPBody = createBodyWithParameters(parameters, filePathKey: filePathKey, data: data, boundary: boundary, fileName:filename, jsonData: jsonData)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
    data, response, error in

    if error != nil {
        println("error=\(error)")
        failed(errorCode: error.code)
        return
    }else{
        var error: NSError?
        var json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error)
        let parsedJson = JSON(json!)
        completion(parsedJSON: parsedJson)
    }
}

task.resume()

I had this same problem. I'm using AFNetworking. Instead of using dataTaskWithRequest I found that I needed to use uploadTaskWithStreamedRequest with a callback for my method, progressCallback .

if request != nil
    {

        let manager = AFURLSessionManager.init(sessionConfiguration: NSURLSessionConfiguration.defaultSessionConfiguration())

        let uploadTask = manager.uploadTaskWithStreamedRequest(request,
            progress:
            { (uploadProgress) -> Void in
                dispatch_async(dispatch_get_main_queue())
                {
                    progressCallback(progress: Float(uploadProgress.fractionCompleted))
                }
            },
            completionHandler:
            { (data, response, error) -> Void in
                if error != nil
                {
                    DDLogSwift.error("There was an error uploading. Error: \(error)")
                }
                else
                {
                    DDLogSwift.debug("Response: \(data)")
                }
            })
        uploadTask.resume()
    }

I use Alamofire (Swift 2.3) to send multipart with progress. Here is code:

func upload(URLRequest: Router, onProgress: (progress: Float?) -> Void, completion: (json: AnyObject?, error: Error?) -> Void) {
    let headers:[String: String] = [:]

    let router = URLRequest.URLRequest
    let tuple = URLRequest.parameters
    let parameters = tuple.0!
    let imagesData = tuple.1
    let url = router.URLString

    self.manager!.upload(
        .POST,
        url,
        headers: headers,
        multipartFormData: { (multipartFormData: MultipartFormData) -> Void in
            for value in imagesData {
                var mimeType = "video/jpg"
                var bodyName = "images"
                let filename = value.uniqueName
                if value.mediaType == ReporterMediaType.image {
                    mimeType = "image/jpg"
                    bodyName = "images"
                } else if value.mediaType == ReporterMediaType.video {
                    mimeType = "video/quicktime"
                    bodyName = "video"
                } else if value.mediaType == ReporterMediaType.videoFrame {
                    mimeType = "image/jpg"
                    bodyName = "videoFrame"
                }
                multipartFormData.appendBodyPart(
                    data: value.data,
                    name: bodyName,
                    fileName: filename,
                    mimeType: mimeType)
            }
            for (key, value) in parameters {
                multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
            }
        },
        encodingCompletion: { (encodingResult) -> Void in
            switch encodingResult {
            case .Success(let upload, _, _):
                upload.responseJSON { response in
                    if response.result.isSuccess || response.response?.statusCode == 200 {
                        completion(json: upload, error: nil)
                    } else {
                        dispatch_async(dispatch_get_main_queue()) {
                            completion(json: nil, error: response.result.error)
                        }
                    }
                }
                upload.progress { _, totalBytesRead, totalBytesExpectedToRead in
                    let progress = Float(totalBytesRead)/Float(totalBytesExpectedToRead)
                    onProgress(progress: progress)
                }
            case .Failure:
                UIApplication.sharedApplication().networkActivityIndicatorVisible = false
                break
            }
    })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM