首页 > 解决方案 > 将上传的 UIImage 作为 PNG 文件发送到服务器

问题描述

我正在尝试将上传的图像发送到服务器。我成功地从照片中获取图像,并将其附加到 ViewController 中的 UIImageView。现在我需要将此图像与其他数据一起发送到服务器。我能够成功发送除图像之外的所有数据。

这是我的功能:

func placeOrder(withOrder: Order) {

    let returnedJobId: String? = UserDefaults.standard.object(forKey: "jobId") as? String
    let returnedOrderPrice: String? = UserDefaults.standard.object(forKey: "orderPrice") as? String

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    let currentDateTime  = formatter.string(from: Date())
    let selectedImage = imagePlaceHolder.image!
    let uploadedFile = selectedImage.jpegData(compressionQuality: 0.5)
    DispatchQueue.main.async {

        let date     = self.chosenTimeDateTextFieldDisplay.text!    
        let address  = self.addressField.text!
        let phone    = self.phoneField.text!
        let comments = self.commentsEntryView.text!
        let file     = uploadedFile
        let jobId    = returnedJobId!
        let price    = returnedOrderPrice!

        let headers = [
            "content-type" : "multipart/form-data",//application/x-www-form-urlencoded",
            "cache-control": "no-cache",
            "postman-token": "dded3e97-77a5-5632-93b7-dec77d26ba99"
        ]

        let user = CoreDataFetcher().returnUser()
        let provider = user.provider_id
        let userID = user.id
        let userType = user.user_type

        let postData = NSMutableData(data: "data={\"user_type\":\"\(userType)\",\"job_id\":\"\(jobId)\",\"user_id\":\"\(userID)\",\"provider_id\":\"\(provider)\",\"order_placing_time\":\"\(currentDateTime)\",\"order_start_time\":\"\(date)\",\"order_address\":\"\(address)\",\"order_phone\":\"\(phone)\",\"order_comments\":\"\(comments)\",\"order_price\":\"\(price)\",\"$_FILES\":\"\(file!)\"}".data(using: String.Encoding.utf8)!)

        let request = NSMutableURLRequest(url: NSURL(string: "http://Api/v2/placeOrder")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                          timeoutInterval: 10.0)

        request.httpMethod          = "POST"
        request.allHTTPHeaderFields = headers
        request.httpBody            = postData as Data

        let session  = URLSession.shared
        let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
            if (error != nil) {
                print(error!)
            } else {
                if let dataNew = data, let responseString = String(data: dataNew, encoding: .utf8) {
                    print(responseString)

                    DispatchQueue.main.async {
                        do {
                            let fetcher = CoreDataFetcher()
                            let json = try JSON(data: data!, options: .allowFragments)
                            let answer = json["answer"]
                            let status = json["status"]
                            let orderID = answer.int!

                            if status == "ok" {
                                print("Status is OK")
                            }

                            fetcher.addOrderID(orderId: orderID, toOrder: withOrder)
                            print("Order id has been saved!")
                        } catch {
                            print("Order ID Counldn't be Saved!")
                        }
                    }

                }

            }
        })

        dataTask.resume()
    }

}

这种方法行不通。因为它应该是一个多部分的表单数据

如何将我的 func 重写为多部分表单数据以将图像转换为 PNG 文件并将其附加到 API 请求中?

标签: iosswiftmultipartform-data

解决方案


您的问题的答案很大程度上取决于您如何尝试将数据发送到服务器。具有讽刺意味的是,您根本没有提供任何相关信息。如果这是基于 JSON 的 API,那么两个最可能的解决方案是:

  • 您需要将数据转换为 base64 字符串
  • 您将需要发送多部分表单数据

这一切都应该在您的 API 文档中的某个地方进行介绍。对于 base64,事情非常简单;你可以使用image.pngData()?.base64EncodedString(). 多部分表单数据有点复杂,但你可以在上面找到很多像这样的帖子。

对于非 JSON,我想您可以只使用正确的内容类型标头 POST 原始数据。但这又取决于 API 的实现。

无论如何,您也可以尝试找出错误(如果有)。


推荐阅读