I've got a generic "perform" method to download some data from the network (Some code omitted):
func perform<D: Decodable>(_ endPoint: EndPoint) -> AnyPublisher<D, APIProviderError> {
do {
let request = try requestBuilder.build(with: endPoint)
return try configurateSession(urlRequest: request, stub: endPoint.testData)
.dataTaskPublisher(for: request)
.decode(type: D.self, decoder: JSONDecoder())
catch {
fatalError(error.localizedDescription)
}
}
- Initially I load the main page structure. json example:
{
"layout": {
"id": "10",
"slots": [
{
"slotNumber": 1,
"widgets": [
{
"id":"10",
"type": "booking"
},
{
"id": "11",
"type": "banners"
},
{
"id":"12",
"type": "chips"
},
{
"id":"13",
"type": "products"
},
{
"id": "15",
"type": "banners"
}
]
}
and parse it into an array of structures
struct Container: Decodable {
let layout: Layout
}
struct Layout: Decodable {
let slots: [Slot]
}
struct Slot: Decodable {
let widgets: [Section]
}
struct Section: Decodable {
private enum CodingKeys: String, CodingKey {
case id, type
}
let id: String
let type: SectionType
var items: [Item]?
}
enum SectionType: String, Decodable {
case banners, brands, products, orders, coupons, map, card, booking, chips
}
- For each widget(Section), depending on its type, I need to load its items and mutate widget. Item examples:
{
"data": [
{
"offerPrice": "59.99",
"name": "ss",
"id": "60461"
},
{
"offerPrice": "79.99",
"name": "www",
"id": "60750"
}]
}
{
"data": [
{
"image": "url"
},
{
"image": "url",
"categoryId": "3074457345616766223"
}
]
}
to
struct ItemContainer<T: Decodable>: Decodable {
let id: String
let items: [T]
}
class Banner: Item, Decodable {
let categoryID: String?
let infoID: String?
let imageURL: String?
}
class Product: Item, Decodable {
let id: String
let name: String
let offerPrice: String
}
I think For each widget it is necessary to create a publisher. I don't understand what to do next. Zip does not work with collections
I wrote the following:
provider.perform(.structMain)
.map { (container: Container) in
container.layout.slots.first?.widgets
}.eraseToAnyPublisher()
.sink(receiveCompletion: { _ in
}, receiveValue: { result in
????????
})
.store(in: &self.cancellableset)
Or do I need something else