Search code examples
swiftparsingfetchdispatchgroup

How to make for-in loop wait for data fetch function to complete


I am trying to fetch bunch of data with for in loop function, but it doesn't return data in correct orders. It looks like some data take longer to fetch and so they are mixed up in an array where I need to have all the data in correct order. So, I used DispatchGroup. However, it's not working. Can you please let me know what I am doing wrong here? Spent past 10 hours searching for a solution... below is my code.

@IBAction func parseXMLTapped(_ sender: Any) {

    let codeArray = codes[0]
    for code in codeArray {
                    
              self.fetchData(code)
                    
     }
                
      dispatchGroup.notify(queue: .main) {
          print(self.dataToAddArray)
          print("Complete.")
     }

}

private func fetchData(_ code: String) {
        dispatchGroup.enter()
        print("count: \(count)")

        let dataParser = DataParser()
        dataParser.parseData(url: url) { (dataItems) in
            self.dataItems = dataItems
            
            print("Index #\(self.count): \(self.dataItems)")
            self.dataToAddArray.append(self.dataItems)

        }
        self.dispatchGroup.leave()
        
        dispatchGroup.enter()
        self.count += 1
        dispatchGroup.leave()
        
    }

Solution

  • In this case, using DispatchSemaphore:

    let semaphore = DispatchSemaphore(value: 0)
    
    DispatchQueue.global().async {
        for code in codeArray {
            self.fetchData(code)
            semaphore.wait()
        }
    }
    
    private func fetchData(_ code: String) {
        print("count: \(count)")
    
        let dataParser = DataParser()
        dataParser.parseData(url: url) { (dataItems) in
            self.dataItems = dataItems
    
            print("Index #\(self.count): \(self.dataItems)")
            self.dataToAddArray.append(self.dataItems)
            semaphore.signal()
        }
    }