0

Let's say I got Int array and array for some class instances

var IDs = [Int]()
var items = [Item]()

For every item in IDs array I want to run async function to request item from server

for id in IDs {
    let item = requestItem(id)
    items.append(item)
}

As requestItem works in async way - how can execute code only after all items are loaded?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
moonvader
  • 19,761
  • 18
  • 67
  • 116

2 Answers2

1
func requestItem(id: Int, completion: @escaping (Item) -> ()) {
    DispatchQueue.global(qos: .background).async {
        let item = Item()
        completion(item)
    }              
}

var IDs = [Int]()
var items = [Item]()

for id in IDs {
    requestItem(id: id) { (derivedItem) in
        items.append(derivedItem)
    }
}
Nader
  • 1,120
  • 1
  • 9
  • 22
  • how can I execute code only after all async calls would be completed? – moonvader May 19 '18 at 04:54
  • @moonvader, I made an edit to `requestItem()` to help clarify. Basically, you will call your completion inside the async queue in `requestItem`, once you have got the value of `item` – Nader May 19 '18 at 05:41
  • Let's say I need to run this function 100 times in parallel and I need to know when all 100 function calls will be completed. I think that solution is with using DispatchGroups – moonvader May 19 '18 at 10:12
  • @moonvader if you are waiting for 100 calls to complete then dispatch groups are the way to go – Nader May 19 '18 at 17:42
0

You have to use completion block for your function which makes server request and need to apply some more logic to show user about something is happening.

var IDs = [Int]()
var items = [Item]()

for id in IDs {
    requestItem(itemId : id, finished : { (objItem : Item) -> Void in
       items.append(objItem)
       // Below condition is to check weather all async service call response are came then hide loader or show items to user, etc. whatever you want to do after get all calls responses  
       if IDs.count == items.count {
           // Show item to user or perform your further operation
       }
    })
}

Function which has completion block

func requestItem(itemId : Int, finished: (objItem : Item) -> Void) {

     print("Item details fetched!")

     // Store your response in your Item class object and pass it like below
     let objItem = Item()  // You constructor or any other logic to store value in objItem 

     // Call finished when you have data initialized in your objItem object
     finished(objItem)
}
Dhaval Dobariya
  • 475
  • 4
  • 9