The Issue
I am running into an issue where I have a loop of network calls (called grabImage), all appending their callback data to the same array, and am correctly using a dispatch group to not leave the function until all network calls are done (until the group's enters/leaves are balanced). However, I have no control over the order in which the callbacks edit the aforementioned array, and am getting random orderings in the data. How do I ensure these callbacks, all occurring in separate threads, run serially to keep an ordering in the global array?
What I’ve tried
I have tried the obvious of using a serial queue, however, because the grabImage function escapes itself, I think the serial queue might think that it’s done executing before it enters the callback
Relevant Code
//function to grab the uploaded pics of a user and store them
func fetchAllImages(_ userPicArray: [String?], _ completion: @escaping ([UIImage]) -> ()) {
var images: [UIImage] = [] //array these async calls are appending to
for photoLink in userPicArray {
//if the picture (link) exists
if photoLink != nil {
//make sure to append to the array asynchronously
appendImagesSQ.sync { //my attempt to run serially
//grab image and add it to the resImages array
self.grabImage(photoLink!) { (image) in //grabImage itself escapes
self.grabImageDispatchGroup.leave()
images.append(image)
}
}
}
}
grabImageDispatchGroup.notify(queue: grabImageSQ) {
completion(images)
}
}