0

I want an alert to be shown according to an async logic.

This is my code :

@IBAction func AddToFavoriteButton(_ sender: Any)
    {
        IsItemInFavoritesAsync(productId: productToDisplay.UniqueID())
        {
            success in

            // Product exists in favorite tree
            Constants.showAlert(title: "Item in Tree", message: "Yes it is", timeShowing: 1, callingUIViewController: self)
        }
        // Product doesn't exist in favorite tree
        Constants.showAlert(title: "Item NOT in Tree", message: "Isn't", timeShowing: 1, callingUIViewController: self)
        Product.RegisterProductOnDatabaseAsFavorite(prodToRegister: productToDisplay, productType: productType)
    }

    private func IsItemInFavoritesAsync(productId: String, completionHandler: @escaping (Bool) -> ())
    {
        let favoriteTree = productType == Constants.PRODUCT_TYPE_SALE ? Constants.FAVORITE_TREE_SALE : Constants.FAVORITE_TREE_PURCHASE
        Constants.refs.databaseRoot.child(favoriteTree).child((Constants.refs.currentUserInformation!.uid)).observeSingleEvent(of: .value, with: {(DataSnapshot) in

            return DataSnapshot.hasChild(self.productToDisplay.UniqueID()) ? completionHandler(true) : completionHandler(false)

        })

    }

What this code snippet does is:

  1. Check if a product was saved to favorites
  2. If it has, show popup A
  3. If it has not, show popup B

I followed another post on StackOverflow that stated that's how I was supposed to call the async function. (Can Swift return value from an async Void-returning block?)

What actually happens is that only popup B shows (the one outside the IsItemInFavoritesAsync closure). What is my mistake?

I guess that IsItemInFavoritesAsync enters the closure upon finishing, and the function IsItemInFavoritesAsync continues onwards to the "Product not in tree" section.

Notice: the function IsItemInFavoritesAsync reads from Firebase.

How do I fix this?

halfer
  • 19,824
  • 17
  • 99
  • 186
Ofri
  • 289
  • 5
  • 17

1 Answers1

1

Both actions (positive result and negative result) need to be inside the completion handler.

So something like this:

IsItemInFavoritesAsync(productId: productToDisplay.UniqueID()) { success in
    if success {
      // Product exists in favorite tree
      Constants.showAlert(title: "Item in Tree", message: "Yes it is", timeShowing: 1, callingUIViewController: self)
    }
    else {
      // Product doesn't exist in favorite tree
      Constants.showAlert(title: "Item NOT in Tree", message: "Isn't", timeShowing: 1, callingUIViewController: self)
      Product.RegisterProductOnDatabaseAsFavorite(prodToRegister: productToDisplay, productType: productType)
    }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807