Swift 4-使用URLSession获取上传图像进度 [英] Swift 4 - Get an Upload Image Progress using URLSession

查看:101
本文介绍了Swift 4-使用URLSession获取上传图像进度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我下面有这种代码

func upload(){
    let img = UIImage(named: "1")
    let imgData = UIImageJPEGRepresentation(img!, 1)
    let data = imgData?.base64EncodedString()

    var request = URLRequest(url: URL(string: url)!)
    request.httpMethod = "POST"
    request.setValue("\(auth)", forHTTPHeaderField: "Authorization")
    request.setValue("application/xml", forHTTPHeaderField: "Content-Type")

    var postString = "<uploadrequest>"
    postString += "<folderid>123</folderid>"
    postString += "<folder_name>images</folder_name>"
    postString += "<image_byte>\(data!)</image_byte>"
    postString += "</uploadrequest>"

    request.httpBody = postString.data(using: .utf8)

    let configuration = URLSessionConfiguration.default
    let session = URLSession(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)

    let task = session.uploadTask(with: request, from: imgData!, completionHandler: {
        (data, response, error) -> Void in

        if let error = error {
            print(error)
            return
        }
        if let data = data {
            _ = self.parseJsonData(data: data)
        }
    })

    task.resume()
}

func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
    print("sent:", totalBytesSent, "from:", totalBytesExpectedToSend)

    let size = totalBytesSent / totalBytesExpectedToSend
    self.progressbar.progress = Float(size)
}

我的目标是使用API​​上传图像并获取图像也上传进度。图像被转换为​​base64,并插入到API的字符串后的< image_byte> \(data!)< / image_byte> 中。

My target is to upload an image using API and get its upload progress too. The image is converted into base64 and inserted at <image_byte>\(data!)</image_byte> on the poststring of the API.

然后我得到的是这样的:

Then what I got was something like this:


已发送:32768 from :927220
发送:65536从:927220
发送:131072从:927220
发送:163840从:927220
发送:262144从:927220
发送:294912从:927220
发送:360448从:927220
发送:393216从:927220
发送:425984从:927220
发送:491520从:927220
发送:524288从:927220
发送:557056从:927220
发送:589824从:927220
发送:622592从:927220
发送:655360从:927220
发送:688128从:927220
发送:720896从:927220
发送:786432从:927220
发送:819200从:927220
发送:851968从:927220
发送:927220从:927220
错误域= NSCocoaErrorDomain代码= 3840 JSON文本不是以数组或对象开头,并且没有允许设置片段的选项。
UserInfo = {NSDebugDescription = JSON文本不是以数组或
对象开头,并且没有允许设置片段的选项。}

sent: 32768 from: 927220 sent: 65536 from: 927220 sent: 131072 from: 927220 sent: 163840 from: 927220 sent: 262144 from: 927220 sent: 294912 from: 927220 sent: 360448 from: 927220 sent: 393216 from: 927220 sent: 425984 from: 927220 sent: 491520 from: 927220 sent: 524288 from: 927220 sent: 557056 from: 927220 sent: 589824 from: 927220 sent: 622592 from: 927220 sent: 655360 from: 927220 sent: 688128 from: 927220 sent: 720896 from: 927220 sent: 786432 from: 927220 sent: 819200 from: 927220 sent: 851968 from: 927220 sent: 927220 from: 927220 Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

但是,如果我使用其他类似的方法(不带uploadTask),则效果很好,但没有上传进度。

But if I am using other methods like this (without uploadTask), it works good but got no upload progress.

let task = URLSession.shared.dataTask(with: request, completionHandler: {
        (data, response, error) -> Void in

        if let error = error {
            print(error)
            return
        }
        if let data = data {
            _ = self.parseJsonData(data: data)
        }
    })

我也尝试过 Alamofire 。带有请求功能的 Alamofire 是成功的,但仍然没有上传进度,而 Alamofire 具有上载函数(multipartformData)的错误:

I've tried Alamofire too. Alamofire with request function was success but still gave no upload progress and Alamofire with uploadfunction (multipartformData) make this error:


responseSerializationFailed(原因:Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(错误:Error Domain = NSCocoaErrorDomain代码= 3840字符3周围的值无效。 UserInfo = {NSDebugDescription =字符3周围的值无效}。)))

responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(error: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 3." UserInfo={NSDebugDescription=Invalid value around character 3.}))

我想知道我的代码是否有误。您能告诉我我该如何处理我的代码吗?还是问题出在我的API上,因为我的API只接受 base64 代码?

I want to know if I make a mistake on my code. Could you tell me what should I do with my code? Or the problem was my API because my API just accepts a base64 code?

如果您想查看我的 Alamofire 代码,它是

If you want to see my Alamofire code, it was there

请,有人帮我解决这个问题。

Please, somebody help me to solve this problem.

谢谢! :)

编辑1

这是我通过请求函数得到的结果(没有上传功能)

This is my result by the request function (without upload function)

{
    "media_preview" =     {
        "image_media" =         {
            fileid = 4928501;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = "product\\66861/images800\\";
            height = 533;
            src = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 800;
        };
        "medium_media" =         {
            fileid = 4928503;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = "product\\66861/images500\\";
            height = 333;
            src = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 500;
        };
        "small_media" =         {
            fileid = 4928503;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = "\product\\66861/images300\\";
            height = 200;
            src = "/zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 300;
        };
        "source_media" =         {
            fileid = 4928499;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = "\\product\\66861images\\";
            height = 666;
            src = "/zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 999;
        };
        "thumbnail_media" =         {
            fileid = 4928507;
            filename = "zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            folderpath = \\product\\66861/thumb\\";
            height = 150;
            src = "/zhzvoHBb1ogda9bps13R5IavYiadCm.jpg";
            width = 150;
        };
    };
    responsestatus =     {
        "access_token" = "<null>";
        code = 00;
        description = Success;
    };
}

编辑2
这是 parseJsonData(data:Data)

func parseJsonData(data: Data) {
    do {
        let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
        print(jsonResult!)
    } catch {
        print(error)
    }
}


推荐答案

对于具有大量参数的图像上传到服务器。尝试此代码 Alamofire 。它可以正常工作。

For image with multple Paramaters Uploading to server. Try this code Alamofire. Its going to work.

Alamofire.upload(multipartFormData: { (multipartFormData : MultipartFormData) in
            let count = imageToUpload.count
            for (key, value) in parameters {
                multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
            }
            for i in 0..<count{
                let image:UIImage = self.loadImage(imageToUpload[i])
                if let imageData = image.jpegData(compressionQuality: 0.5) {
                    let imageName  = "image[\(i)]"
                    multipartFormData.append(imageData as Data, withName:imageName , fileName: imageToUpload[i], mimeType: "image/jpeg")
                }
            }
        }, usingThreshold: UInt64.init(), to: serviceUrl, method: .post, headers: headers)  { (result) in
            switch result {
            case .success(let upload, _ , _):
                upload.uploadProgress(closure: { (progress) in
                    print("uploding: \(progress.fractionCompleted)")
                })
                upload.responseJSON { response in
                    if response.result.isFailure {
                        if let err = response.error{
                            print(err)
                        }
                        return
                    }

                    guard let jsonData = response.result.value else {                           
                        return
                    }
                    //

                    do{
                        let json = try JSONSerialization.jsonObject(with: response.data as! Data, options: [])
                        print("josnResposne:\(json)")

                    } catch let parsingError {
                        print("Error", parsingError)
                    }

                }
            case .failure(let encodingError):
                print("failed")
                print(encodingError)                                        
            }
        }

这篇关于Swift 4-使用URLSession获取上传图像进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆