当前位置: 首页 > 知识库问答 >
问题:

Swift 4-使用URLSession获取上传图像进度

诸葛立果
2023-03-14

我在下面有这样的代码

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上传图像,并获得其上传进度。将图像转换为base 64并插入到

然后我得到的是这样的东西:

发送: 32768从: 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 Code=3840"JSON文本没有以数组或对象开始,并且选项允许不设置片段。"JSON文本没有以数组或对象开始,并且选项允许不设置片段。}

但是如果我使用其他类似的方法(没有uploadTask),它工作得很好,但是没有上传进度。

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)
        }
    })

我也尝试了AlamofireAlamofire请求函数是成功的,但仍然没有给出上传进度和Alamofire上传函数(MultipartformData)使此错误:

responseSerializationFailed(原因:Alamofire.AFError.ResponseSerializationFaileureReason.jsonSerializationFailed(错误:错误域=NSCOCAERRORDOMAIN代码=3840“字符3周围的无效值”。用户信息={NSDebugDescription=字符3周围的无效值。}))

我想知道我的代码是否出错。你能告诉我该怎么处理我的代码吗?或者问题出在我的应用编程接口上,因为我的应用编程接口只接受一个bas64代码?

如果你想看我的Alamofirecode,它就在那里

拜托,谁来帮我解决这个问题。

谢谢!:)

编辑1

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

{
    "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)

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

共有2个答案

穆城
2023-03-14

要获取进度,请使用URLSession的以下委托方法,您可以在didReceiveData方法中获取进度

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {

        //here you can get full lenth of your content
        expectedContentLength = Int(response.expectedContentLength)
        println(expectedContentLength)
        completionHandler(NSURLSessionResponseDisposition.Allow)
    }

    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {


        buffer.appendData(data)

        let percentageDownloaded = Float(buffer.length) / Float(expectedContentLength)
        progress.progress =  percentageDownloaded
    }

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        //use buffer here.Download is done
        progress.progress = 1.0   // download 100% complete
    }
邹英发
2023-03-14

对于具有多个参数上传到服务器的图像。试试这个代码Alamofire。它去工作。

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)                                        
            }
        }
 类似资料:
  • 我正试图用Alamofire将图像上传到服务器,但我的代码不起作用。这是我的代码: 这是urlRequestWithComponents方法: 这就是我在控制台得到的: 请求{URL:http://tranthanhphongcntt.esy.es/task_manager/IOSFileUpload/ }响应可选({URL:http://tranthanhphongcntt.esy.es/tas

  • 经过一些研究,我发现了一个用于多部分文件上传的开放库。在我的情况下,我想上传一个图像使用PUT请求,其中的图像要么是从画廊或相机选择。以下是我正在使用的资源:1。https://github.com/gotev/android-upload-service2.https://www.simplifiedcoding.net/android-upload-image-to-server/#comme

  • 我正在使用翻新上传图像/文件 在这里,我发布了我的API调用以上传图像 请帮助我如何为这个调用编写接口,我已经用@part和@PartMap试过了,但是不起作用

  • 我正在制作一个应用程序,让用户使用AWS S3将他们的视频上传到我们的终端。我使用服务器生成签名url并将其返回给客户端(Web浏览器),然后客户端使用该url上传到我们的后端。它工作得很好,但我有一个小问题,我们无法跟踪从浏览器开始的文件上传的进度。 那么,有什么方法可以让我们从服务器上获得上传进度呢?

  • 我想首先捕获图像并将其查看到ImageView,然后单击将图像保存到FireBase。

  • 我在我的屏幕上有四个图像视图,从相机中捕获图像并显示在其中,现在我想将这些图像上传到服务器上。因此,我使用了下面的代码来获取它们的路径,但它通过了异常。是否有可能从摄像机拍摄的图像视图将图像上传到服务器(无需将图像存储到内存中)。