使用URLSession.shared.uploadTask将图像和参数上传到API

时间:2019-04-26 08:34:54

标签: ios swift nsurlsessionuploadtask

我正在尝试解决如何使用swift将一组参数和一个图像文件上传到我的API。

我的代码大约在此时:

//parameters
    let actualParameters = ["email": myEmail, "token": myToken, "certnbr": certnbr, "title": title, "newCert": newCert, "expires": expires, "expiryDate": expiryDate, "issueDate": issueDate] as! [String : Any]

    let parameters = NewCertModel(email: "email")

    //create the url with URL
    let url = URL(string: "http://127.0.0.1:8000/api/newCertification/")!

    //now create the URLRequest object using the url object
    var request = URLRequest(url: url)

    request.httpMethod = "POST"
    let boundary = "Boundary-\(UUID().uuidString)"
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    request.httpBody = createBody(parameters: params,
                            boundary: boundary,
                            data: UIImageJPEGRepresentation(chosenImage, 0.7)!,
                            mimeType: "image/jpg",
                            filename: "hello.jpg")

    guard let uploadData = try? JSONEncoder().encode(parameters) else {
        print("Error Upload Data")
        return
    }


    //new session
    URLSession.shared.uploadTask(with: request as URLRequest, from: jsonData as! Data) { (responseData, response, error) in
                                    // Check on some response headers (if it's HTTP)
                                    if let httpResponse = response as? HTTPURLResponse {
                                        switch httpResponse.statusCode {
                                        case 200..<300:
                                            print("Success")
                                        case 400..<500:
                                            print("Request error")
                                        case 500..<600:
                                            print("Server error")
                                        case let otherCode:
                                            print("Other code: \(otherCode)")
                                        }
                                    }

                                    // Do something with the response data
                                    if let
                                        responseData = responseData,
                                        let responseString = String(data: responseData, encoding: String.Encoding.utf8) {
                                        print("Server Response:")
                                        print(responseString)
                                    }

                                    // Do something with the error
                                    if let error = error {
                                        print(error.localizedDescription)
                                    }
    }

    .resume()
    }
}

代码不是完美的,因为我已经尝试了很多解决方案,但现在它们有些混乱。我能够轻松地将数据传递到我的api,但是文件上传/分段操作使我很困惑。我正在寻找很难找到且非常有限的资源,尤其是来自全职Android开发职位的资源。

我可以切换到Alamofire,但我的整个项目尚未使用它。我想等待切换。我已经轻松地花了5个小时尝试组合,以显示通过的数据最少,但是什么也没有。

这是我的python代码的开始:

if request.method == 'POST':

email = request.POST.get('email')
token = request.POST.get('token')
certnbr = request.POST.get('certnbr')
title = request.POST.get('title')
newCert = request.POST.get('newCert')
expires = request.POST.get('expires')
expirydate = request.POST.get('expiryDate')
issuedate = request.POST.get('issueDate')
picfile = request.FILES.get('image')

data = {}

#get the user
u = Usr.objects.get(email__iexact=email)

一些我不走运的消息来源:

fluffy.es-“这段代码对我来说太草率了?”

medium article-“我找不到在此处传递参数的提示”

stackoverflow

more stackoverflow

further stackoverlow

令我惊讶的是,所有这些来源之间都存在这种不一致,甚至只有少数几个甚至使用uploadTask,此外,我还阅读了十几个看似不同的内容。最终Alamofire是最佳选择吗?苹果为什么不采用它呢?整个过程非常困难,非常感谢您的事先帮助。

编辑: 我切换到Alamofire,立刻变得更容易。

1 个答案:

答案 0 :(得分:0)

虽然不是我问题的最佳答案,但是Alamofire代码更干净。因此,为了节省未来,我有些压力。只需使用Alamofire。

Alamofire Github

let ImageData = imageobj.pngData()
    let urlReq = URL(string: "http://127.0.0.1:8000/api/newCertification/")!
    print("params")
    let params : Parameters = ["email": myEmail, "token": myToken, "certnbr": certnbr, "title": title, "newCert": newCert, "expires": expires, "expiryDate": expiryDate as Any, "issueDate": issueDate as Any]
    print("time to upload")
    Alamofire.upload(multipartFormData: { multipartFormData in
        multipartFormData.append(ImageData!, withName: "avatar",fileName: "file.jpg", mimeType: "image/jpg")
        for (key, value) in params {// this will loop the 'parameters' value, you can comment this if not needed
            multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
        }
    },
                     to:urlReq)
    { (result) in
        switch result {
        case .success(let upload, _, _):

            upload.uploadProgress(closure: { (progress) in
                print("Upload Progress: \(progress.fractionCompleted)")
            })

            upload.responseJSON { response in
                //completion("success")
            }

        case .failure(let encodingError):
            print(encodingError)
            //completion("failed")


    }
}