多部分请求 - 带有 UIImage 的可编码结构

Posted

技术标签:

【中文标题】多部分请求 - 带有 UIImage 的可编码结构【英文标题】:Multipart request - Encodable struct with UIImage 【发布时间】:2019-09-30 08:45:58 【问题描述】:

在 Swift 5 中,我试图削减很多依赖项 (Alamofire),并且我试图了解如何在使用 Codable 和 URLRequest 时执行多部分请求

我的代码可以正常使用名称和电子邮件创建用户,但我需要在结构中添加头像。

添加头像后,如何将结构编码为多部分请求。 我在网上找到了一些解决方案,但不适用于我正在尝试实施的场景。

下面的代码是没有头像的请求的工作代码。

struct User: Codable 
    let name: String
    let email: String?

var endpointRequest = URLRequest(url: endpointUrl)
endpointRequest.httpMethod = "POST"
endpointRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
do 
   endpointRequest.httpBody = try JSONEncoder().encode(data)
 catch 
   onError(nil, error)
   return



URLSession.shared.dataTask(
    with: endpointRequest,
    completionHandler:  (data, urlResponse, error) in
        DispatchQueue.main.async 
            self.processResponse(data, urlResponse, error, onSuccess: onSuccess, onError: onError)
        
).resume()

【问题讨论】:

【参考方案1】:

UIImage 不符合 Codable 但您可以对 pngData 表示进行编码。但是这需要实现Codable 方法

struct User: Codable 
    let name: String
    let email: String?
    var avatar : UIImage?

    private enum CodingKeys : String, CodingKey  case name, email, avatar 

    init(from decoder: Decoder) throws 
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        email = try container.decodeIfPresent(String.self, forKey: .email)
        if let avatarData = try? container.decode(Data.self, forKey: .avatar) 
            avatar = UIImage(data: avatarData)
        
    

    func encode(to encoder: Encoder) throws 
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        try container.encode(email, forKey: .email)
        if let avatarImage = avatar 
            try container.encode(avatarImage.pngData(), forKey: .avatar)
        
    

或者将avatar声明为URL,单独发送图片

【讨论】:

以上是关于多部分请求 - 带有 UIImage 的可编码结构的主要内容,如果未能解决你的问题,请参考以下文章

带有可编码数组的 swift 5 抽象网络响应

Swift 4 可编码;如何使用单个根级密钥解码对象

如何在可编码结构中使用计算属性(swift)

如何为以下 API 数据创建可编码结构

使用可编码和静态变量的 Plist 结构类

获取UIImage,将其转换为多部分图像字符串,写入文本文件iOS