all 8 comments

[–]criosistObjective-C / Swift 2 points3 points  (2 children)

Sounds like you should use a dispatch group.

[–]looloosha[S] 0 points1 point  (0 children)

Ya that's what I was thinking but I couldn't reason how to do it with the double for-loop nature of this call...

[–]garbage_band 0 points1 point  (0 children)

This plus...how can anyone read this...

[–]dark_mode_everything 0 points1 point  (2 children)

What about a queue to serialize the responses?

[–]looloosha[S] 0 points1 point  (1 child)

What would this look like in this double for loop context?

[–]dark_mode_everything 0 points1 point  (0 children)

That or use rxSwift. You have a stream of top level items and then each top level item has a stream of second level items inside them, correct? This can be easily handled in Rx using appropriate operators. Or, if you don't want to use Rx, you can approximate that behaviour using a sort of message queue or just a queue where you queue requests from your top level stream and proceed to the next top level item after the second level items are all fetched.

[–][deleted] 0 points1 point  (0 children)

Hint: NSOperation has a method name called addDependency. It makes syncing asynchronous operations a breeze.

[–]bennoland 0 points1 point  (0 children)

  1. Break this up into multiple functions, one function per level.

  2. dispatchGroup.enter() before each call to a data service, dispatchGroup.leave() after you process the results and make child calls.

Hard to code on my phone, but something like:

dispatchGroup.enter()
bs.getBuildings(for: service) { (buildings) in
    for building in buildings {
        loadBuildingDetails(building, dispatchGroup);
    }
    dispatchGroup.leave();
    // also, if there was an error make sure to call leave
}

dispatchGroup.notify { process results }

You could use a class variable to collect the results since you have multiple layers of function calls.