代码之家  ›  专栏  ›  技术社区  ›  catcatcat

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

  •  0
  • catcatcat  · 技术社区  · 7 年前

    我在下面有这样的代码

    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并插入到 <image_byte>\(data!)</image_byte> 在API的poststring上。

    然后我得到的是这样的:

    发送: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 Error Domain=NSCocoaErrorDomain Code=3840“JSON文本未以数组或对象开头,并且未设置允许片段的选项。” UserInfo={NSDebugDescription=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)
            }
        })
    

    我试过了 Alamofire 也 阿拉莫菲尔 具有 request 功能成功,但仍然没有提供上载进度,并且 阿拉莫菲尔 具有 upload 函数(multipartformData)出现以下错误:

    我想知道我的代码是否出错。你能告诉我该怎么处理我的代码吗?或者问题是我的API,因为我的API只接受 base64 密码

    如果你想看看我的 阿拉莫菲尔 代码,它是 there

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

    谢谢!:)

    编辑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: 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 回复  |  直到 7 年前
        1
  •  0
  •   AtulParmar    7 年前

    要获得进度,请使用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
        }
    
        2
  •  -1
  •   Abdul Hoque Nuri    7 年前

    对于上载到服务器的具有多个参数的图像。尝试此代码 阿拉莫菲尔 . 它会起作用的。

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