Chaining multiple requests in Combine

Viewed 37

I am trying to nest multiple request together to create the object that I need. Just a short description about the API and what I try to accomplish. I am basically fetching an array of exercises. These exercise however don't have every information that I need so I have to take the id and do another request to get the whole object. From there on I get an array of images which contains the url that I need. Then I need another attribute called variations which consists of an array of exercise ids.

So I basically need to do 4 requests:

  • Fetch all exercises
  • fetch exercise by id
  • From there I take the image urls and fetch the images
  • Then I want to fetch all the variations using the ids from the array

So my new object should be an array of type:

struct ExerciseDetails: Hashable {
    
    let id: Int
    let title: String
    let image: [UIImage]
    let variations: [ExerciseDetails]
}

Here is what I am trying to do:

URLSession.shared.dataTaskPublisher(for: URL(string: "https://wger.de/api/v2/exercise/?limit=70&offset=40"))
            .map { $0.data }
            .decode(type: [Exercise].self, decoder: JSONDecoder())
            .map { $0.map { $0.id } }
            .flatMap(\.publisher)
            .flatMap { id in
                URLSession.shared.dataTaskPublisher(for: URL(string: "https://wger.de/api/v2/exerciseinfo/\(id)")!)
                    .map(\.data)
                    .decode(type: Exercise.self, decoder: JSONDecoder())
                    .map { $0.images }
                    .flatMap { image in
                        URLSession.shared.dataTaskPublisher(for: URL(string: image.imageUrl))
                            .map { return UIImage(data: $0.data) }
                    }
            }
            .map { $0.map { $0.variations } }
            .flatMap(\.publisher)
            .flatMap { id in
                URLSession.shared.dataTaskPublisher(for: URL(string: "https://wger.de/api/v2/exerciseinfo/\(id)")!)
                    .map(\.data)
                    .decode(type: Exercise.self, decoder: JSONDecoder())
                    .map { return $0 }
            }

Now I don't know how to map the output to -> [ExerciseInfo]

I think I am on a good way but there is something missing.

Can anybody help?

0 Answers
Related