Reputation: 343
I'm having hard time trying to decode response. I need response body and one response header and I also need to customize my decoding process using LossyCodableList
to make sure parsing will be successful even if some elements in response body are incorrect. My first solution is: I get response data with headers, then I map it into my response model using standard .init() and it works, but in this case my problem is that init from decoder
has never been called hence I can't customize decoding process with LossyCodableList
.
func programs(request: CardsRequest) -> AnyPublisher<CardListResponse, Error> {
apiClient.request(.programs(request)).map {
let cardListItem: CardListResponse =
.init(
totalProgramsNumber: $0.headers?["total"] as? String ?? "0",
cardsData: $0.data
)
return cardListItem
}
.eraseToAnyPublisher()
}
struct CardListResponse: Decodable {
var totalProgramsNumber: String?
let cardsData: [CardListItem]
enum CodingKeys: String, CodingKey {
case totalProgramsNumber
case cardsData
}
init(totalProgramsNumber: String? = "0", cardsData: [CardListItem]) {
self.totalProgramsNumber = totalProgramsNumber
self.cardsData = cardsData
}
init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.totalProgramsNumber = try? container.decode(String.self, forKey: .totalProgramsNumber)
do {
let elements = try container.decode(LossyCodableList<CardListItem>.self, forKey: .cardsData)
cardsData = elements.elements
} catch {
cardsData = []
}
}
}
I also tried another solution: I removed standard .init() and now init from decoder
has been called but I don't understand how to get and use data from headers in structure CardListResponse
.
func programs(request: CardsRequest) -> AnyPublisher<CardListResponse, Error> {
apiClient.request(.programs(request)).map { $0.data }
.eraseToAnyPublisher()
}
struct CardListResponse: Decodable {
var totalProgramsNumber: String?
let cardsData: [CardListItem]
enum CodingKeys: String, CodingKey {
case totalProgramsNumber
case cardsData
}
init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.totalProgramsNumber = try? container.decode(String.self, forKey: .totalProgramsNumber)
do {
let elements = try container.decode(LossyCodableList<CardListItem>.self, forKey: .cardsData)
cardsData = elements.elements
} catch {
cardsData = []
}
}
}
Any advice would be appreciated.
Upvotes: 0
Views: 43