MikeG MikeG - 7 months ago 17
Swift Question

How to iterate thru array with asynchronous method, and put return values into an array in the PROPER order

I have an array that holds x number of values(no more than 25). Each value corresponds to an item object that i wish to retrieve from a remote endpoint. I use the following method to retrieve the item object for each corresponding identifier...

func getValues(valueIDs: [Int]){

var values = [Item]()
let group = dispatch_group_create()

for i in 0...valueIDs.count-1 {
dispatch_group_enter(group)

Item.special(valueIDs[i], completion: ({ result in
if let value = result.response.result {
values.append(value)
dispatch_group_leave(group)
}
})
)
}

dispatch_group_notify(group, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
print("the values are \(values)")
}

}


The method is asynchronous, so each call to it in the for-loop returns immediately and the loop finishes iterating thru all the values before any of the values return. I use a dispatch_group to be notified of when all the calls have returned.

The problem I have is that I need to have the retrieved values be put into my array, in the same order that they were called for. Currently, they are appended to the array when they are returned so they are randomly ordered. I do not want to put all the calls on a serial queue and make them wait for each other, that would take too long. Any advice would be great!!

Answer

Check if this works, declaring a fixed length array and accessing the array element by index:

func getValues(valueIDs: [Int]){

    var items = [Item?](count: valueIDs.count, repeatedValue: nil)
    let group = dispatch_group_create()

    for i in 0...valueIDs.count-1 {
        dispatch_group_enter(group)

        Item.special(valueIDs[i], completion: ({ result in
            if let value = result.response.result {
                items[i] = value
                dispatch_group_leave(group)
            }
        })
        )
    }

    dispatch_group_notify(group, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
        print("the values are \(items)")
    }

}
Comments