使用for循环中的异步调用处理完成

时间:2020-07-16 16:18:47

标签: ios swift closures completionhandler

我有一个函数,应该有一个completion-handler,只有在其中的所有内容都实际完成后才能调用。那是我的功能:

static func getWishes(dataSourceArray: [Wishlist], completion: @escaping (_ success: Bool, _ dataArray: [Wishlist]) -> Void){
    
    var dataSourceArrayWithWishes = dataSourceArray
    
    let db = Firestore.firestore()
    let userID = Auth.auth().currentUser!.uid
    
    for list in dataSourceArray {
        db.collection("users").document(userID).collection("wishlists").document(list.name).collection("wünsche").order(by: "wishCounter").getDocuments() { ( querySnapshot, error) in
            if let error = error {
                print(error.localizedDescription)
                completion(false, dataSourceArrayWithWishes)
            } else {
                // append every Wish to array at wishIDX
                for document in querySnapshot!.documents {
                    let documentData = document.data()
                    let imageUrlString = document["imageUrl"] as? String ?? ""
                    
                    let imageView = UIImageView()
                    imageView.image = UIImage()
                    if let imageUrl = URL(string: imageUrlString) {
                        let resource = ImageResource(downloadURL: imageUrl)
                        imageView.kf.setImage(with: resource) { (result) in
                            switch result {
                            case .success(_):
                                dataSourceArrayWithWishes[wishIDX].wishes.append(Wish(name: name, link: link, price: price, note: note, image: imageView.image!, checkedStatus: false))
                                completion(true, dataSourceArrayWithWishes)
                                print("success")
                            case .failure(_):
                                print("fail")
                            }
                        }
                    } else {
                       dataSourceArrayWithWishes[wishIDX].wishes.append(Wish(name: name, link: link, price: price, note: note, image: imageView.image!, checkedStatus: false))
                    } 
                }
            }
        }
    }
}

问题出在imageView.kf.setImage... 现在,我在第一个completion之后调用.success,但是只有在for-loop和所有setImages完成时才应完成该功能。我现在已经尝试了几件事,但无法使其正常工作。因此,我想知道这种情况下的最佳做法是什么?

1 个答案:

答案 0 :(得分:1)

这是您使用DispatchGroup的方式... DispatchGroup循环完成后,您需要asynchronous来得到通知

 static func getWishes(dataSourceArray: [Wishlist], completion: @escaping (_ success: Bool, _ dataArray: [Wishlist]) -> Void){
       
       var dataSourceArrayWithWishes = dataSourceArray
       
       let db = Firestore.firestore()
       let userID = Auth.auth().currentUser!.uid
        let group = DispatchGroup()
    
       for list in dataSourceArray {
        
        group.enter()
           db.collection("users").document(userID).collection("wishlists").document(list.name).collection("wünsche").order(by: "wishCounter").getDocuments() { ( querySnapshot, error) in
            defer{ group.leave() }
               if let error = error {
                   print(error.localizedDescription)
                   completion(false, dataSourceArrayWithWishes)
               } else {
                   // append every Wish to array at wishIDX
                   for document in querySnapshot!.documents {
                    group.enter()
                       let documentData = document.data()
                       let imageUrlString = document["imageUrl"] as? String ?? ""
                       
                       let imageView = UIImageView()
                       imageView.image = UIImage()
                       if let imageUrl = URL(string: imageUrlString) {
                           let resource = ImageResource(downloadURL: imageUrl)
                           imageView.kf.setImage(with: resource) { (result) in
                            defer{ group.leave() }
                               switch result {
                               case .success(_):
                                   dataSourceArrayWithWishes[wishIDX].wishes.append(Wish(name: name, link: link, price: price, note: note, image: imageView.image!, checkedStatus: false))
                                   
                               case .failure(_):
                                   print("fail")
                               }
                           }
                       } else {
                          dataSourceArrayWithWishes[wishIDX].wishes.append(Wish(name: name, link: link, price: price, note: note, image: imageView.image!, checkedStatus: false))
                       }
                   }
               }
           }
       }
    
    group.notify(queue: DispatchQueue.main) {
        completion(true, dataSourceArrayWithWishes)
        print("success")
    }
   }