Как использовать Dispatch Group в цикле с асинхронной функцией Swift?

Я проверил все вопросы по этой теме, но ни один из них не помог. У меня есть код, как показано ниже. Теперь, как только код попадает вfor id in stringArray цикл, он выполняется для stringArray.countраз, даже не входя в асинхронную часть firestore. Это понятно, но не мое требование. я хочуmyGroup.notifyдля выполнения после завершения цикла и асинхронного кода. Но поскольку цикл завершается легко и поэтомуmyGroup.notifyвызывается, даже если асинхронный процесс еще не завершен. Так что, возможно, я прошу здесь разместитьmyGroup.enter а также myGroup.leaveв правильных местах. Спасибо!

MyCode:

func Promise_searchedDataFromDB(stringArray:[String]) {
    for id in stringArray {
        myGroup.enter()
    collectionRef.getDocuments { (querySnapshot, error) in
        if error != nil {
            return
        }
        else {
               guard let snapshot = querySnapshot else {return}
               for document in snapshot.documents {
                
                let myData = document.data()
                if StaticVariable == true {
             
                    self.typeOfListing = myData["Type"] as? String ?? "Not Found"
                    self.charges = Int(myData["Charges"] as? String ?? "Not Found") ?? 0
                    self.nameOfListing = myData["Title"] as? String ?? "Not Found"
                    self.currency = myData["Currency"] as? String ?? "Not Found"
                    self.days = myData["Days"] as? String ?? "Not Found"
                    self.details = myData["Description"] as? String ?? "Not Found"
                    self.cityName = myData["City"] as? String ?? "Ghost"
                    
                    let dataArray = CellComponents(image: UIImage(named: "b")!, typeOfListing: self.typeOfListing , charges: self.charges, rating: 4.1, nameOfListing: self.nameOfListing , cityName: self.cityName, detail: self.details, currency: self.currency, days: self.days)
                    self.ArrayToHoldSearchedListing.append(dataArray)
                    self.tableView.reloadData()
                }
              }
            }
          }

             myGroup.leave()
       }
        
        myGroup.notify(queue: .main) {
            print("All done")
        }
   }

1 ответ

Решение

Оставьте в блоке async, а не за его пределами... и enter должно быть равно, чтобы оставить, поэтому поместите его в оператор defer, чтобы он всегда выполнялся перед выходом из области

  func Promise_searchedDataFromDB(stringArray:[String]) {
     for id in stringArray {
         myGroup.enter()
     collectionRef.getDocuments { (querySnapshot, error) in
        defer{  myGroup.leave() }
        
         if error != nil {
             return
         }
         else {
                guard let snapshot = querySnapshot else {return}
                for document in snapshot.documents {
                 
                 let myData = document.data()
                 if StaticVariable == true {
              
                     self.typeOfListing = myData["Type"] as? String ?? "Not Found"
                     self.charges = Int(myData["Charges"] as? String ?? "Not Found") ?? 0
                     self.nameOfListing = myData["Title"] as? String ?? "Not Found"
                     self.currency = myData["Currency"] as? String ?? "Not Found"
                     self.days = myData["Days"] as? String ?? "Not Found"
                     self.details = myData["Description"] as? String ?? "Not Found"
                     self.cityName = myData["City"] as? String ?? "Ghost"
                     
                     let dataArray = CellComponents(image: UIImage(named: "b")!, typeOfListing: self.typeOfListing , charges: self.charges, rating: 4.1, nameOfListing: self.nameOfListing , cityName: self.cityName, detail: self.details, currency: self.currency, days: self.days)
                     self.ArrayToHoldSearchedListing.append(dataArray)
                     self.tableView.reloadData()
                 }
               }
             }
           }

            
        }
         
         myGroup.notify(queue: .main) {
             print("All done")
         }
    }
Другие вопросы по тегам