Многокомпонентный запрос - кодируемая структура с UIImage - PullRequest
0 голосов
/ 30 сентября 2019

С помощью 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 Ответ

0 голосов
/ 30 сентября 2019

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 и отправить изображение отдельно

...