1

I've spent a fun couple of hours trying all sorts of different combinations to have a label properly update its title after a Firebase async download. It's the same issue raised here and here. Seems like a clear fix, but I'm doing something wrong and would appreciate any help pointing me in the right direction.

The basic flow is view loads, data is downloaded from Firebase, some labels are updated accordingly with downloaded data. One representative iteration I have tried is as follows:

        // Query Firebase.
        let detailsRef = self.ref.child("eventDetails")
        detailsRef.queryOrdered(byChild: "UNIQUE_ID_EVENT_NUMBER").queryEqual(toValue: eventID).observeSingleEvent(of: .value, with: { snapshot in

            if (snapshot.value is NSNull) {
                print("error")
            }
            else {

                var tempDict = [NSDictionary]()

                for child in snapshot.children {

                    let data = child as! FIRDataSnapshot
                    let dict = data.value as! NSDictionary as! [String:Any]
                    tempDict.append(dict as NSDictionary)
                }

                self.dictionaryOfRecoDetails = tempDict
                self.ParseFirebaseData()

                DispatchQueue.main.async {
                    // This is the function that updates labels and button text in format like self.websiteLabel.titleLabel?.text = "Appropriate String"
                    self.loadDataForView()
                }
            }
        })


func loadDataForView() {

    // Example of the label update that happens within this function.
    // Do not show website button if there is no website.
    if self.recommendation.recommendationWebsiteUrl == "" || self.recommendation.recommendationWebsiteUrl == nil || self.recommendation.recommendationWebsiteUrl == "NA" {

        self.websiteLabel.titleLabel?.text = ""
        self.websiteHeight.constant = 0
        self.websiteBottom.constant = 0
    }
    else {
        self.websiteLabel.titleLabel?.text = "Go to Website"
    }
}

EDIT UPDATE: The call to the code above is coming from viewDidAppear(). It doesn't update if I call it from viewDidLayoutSubviews() either.

From debugging I know the label update is getting called, but nothing is changing. Feels like something simple I'm missing, but I'm stuck. Thanks for your ideas.

Community
  • 1
  • 1
Ben
  • 3,346
  • 6
  • 32
  • 51
  • You should call update label directly in the `DispatchQueue.main.async`, do not call self.loadDataForView() in `DispatchQueue.main.async`. – nynohu Nov 11 '16 at 04:30
  • @nynohu it should be the same, but worth a try to see if it fix, i dont see problem in this code – Tj3n Nov 11 '16 at 04:32
  • Did you try it? I had got the same problem as you got and I fixed it by call directly update view in main thread. – nynohu Nov 11 '16 at 04:34
  • 1
    Whether I call the function to update the label or directly update within DispatchQueue.main.async doesn't make a difference. – Ben Nov 11 '16 at 05:20
  • How many times does `loadDataForView` get called? Could it be that it is called once where the contained `if` is passing, and so it sets the width & height to zero. And then the second time it is actually setting the text, but the auto-layout constraints are still zero? – Michael Nov 11 '16 at 06:10
  • Put a breakpoint there, check if it's going inside the `else` statement or not. I believe it might be going inside the `if` statement. Please let me know – KrishnaCA Nov 11 '16 at 07:07

2 Answers2

0

I'm pretty sure you don't need the DispatchQueue.main.async bit. Just try calling self.loadDataFromView() and see if that helps.

Todd Kerpelman
  • 16,875
  • 4
  • 42
  • 40
0

This ended up being a lesson in mis-labeling causing confusion. The label being changed actually isn't a label, but a button. Shouldn't have been named websiteLabel! Once the title was changed with self.websiteLabel.setTitle("Go to Website", for: .normal) then everything worked as expected.

Ben
  • 3,346
  • 6
  • 32
  • 51