如何使用Swift 5通过多部分/表单数据从图库上传iOS图像

xlpyo6sf  于 2022-12-05  发布在  iOS
关注(0)|答案(1)|浏览(236)

我从iOS图库中选择了UIImage对象,并希望通过API上的HTTP使用multipart/form-data发送。它与Postman和Node.js一起工作,但我在Swift的相同请求中遇到了问题。
初始化部分

import Foundation

var image: UIImage?
let postURL = "http://......"

extension NSMutableData {
  func appendString(_ string: String) {
    if let data = string.data(using: .utf8) {
      self.append(data)
    }
  }
}

请求准备

let imageJpeg: Data = image?.jpegData(compressionQuality: 1)

func convertFiledData(fieldName: String, fileName: String, mimeType: String, fileData: Data, fileString: String, using boundary: String) -> Data {
    let data = NSMutableData()
                  
    data.appendString("--\(boundary)\r\n")
    data.appendString("Content-Disposition: form-data; name=\"\(fieldName)\"; file=\"\(fileName)\"\r\n")
    data.appendString("Content-Type: \(mimeType)\r\n\r\n")
    data.append(fileData)
    data.appendString("\r\n")
    data.appendString("--\(boundary)--\r\n")
    
    return data as Data
}

let boundary = "Boundary-\(UUID().uuidString)"

var request = URLRequest(url: URL(string: postURL)!, timeoutInterval: Double.infinity)

request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

request.httpMethod = "POST"
let mimeType = "image/jpeg"

let httpBody = convertFiledData(fieldName: "file",
                                fileName: "xray1.jpg",
                                mimeType: mimeType,
                                fileData: imageJpeg,
                                fileString: imageString,
                                using: boundary)
                
request.httpBody = httpBody as Data

请求零件

URLSession.shared.dataTask(with: request) { (data, res, err) in
    do {
       if let data = data {
       let result = try JSONDecoder().decode(PostModel.self, from: data )
           } else {
              print("No data")
           }
           } catch (let error) {
             print(error.localizedDescription)
             }
 }.resume()

请求运行良好。正文按需组装。我有422 HTTP错误代码。
有res对象显示

Optional(<NSHTTPURLResponse: 0x600001e9e0a0> { URL: http://.... } { Status Code: 422, Headers {
    "Content-Length" =     (
        110
    );
    "Content-Type" =     (
        "application/json"
    );
    Date =     (
        "Mon, 20 Dec 2021 04:30:59 GMT"
    );
    Server =     (
        uvicorn
    );
} })

这是FastAPi服务器发送的URLSession数据中的数据

{"detail":[{"loc":["body","file"],"msg":"Expected UploadFile, received: <class 'str'>","type":"value_error"}]}

这看起来像是文件数据格式的问题。可能是在. jsonData()部分。我尝试了一些其他的转换,但没有任何结果。
知道吗?谢谢!

mzmfm0qo

mzmfm0qo1#

我不知道你是否解决了这个问题,但我认为问题可能在于这一行:
data.appendString("Content-Disposition: form-data; name=\"\(fieldName)\"; file=\"\(fileName)\"\r\n")
最后一部分应该是filename=\"\(fileName)\"\r\n
我得到了一个类似的错误响应,但在我的情况下,问题是我没有通过扩展名.jpg后的文件名,一些服务器不承认你的图像文件没有扩展名。
把这个答案留在这里作为参考,以防人们遇到类似的问题。

相关问题