0

From the documentation I see that I can get some user data (which I'm already getting correctly), however, the way it's structured, it doesn't allow me to access the array outside of it, this is what I mean, I have a function:

    func observe() {
        let postsRef = Database.database().reference(withPath: "post")

        struct test {
            static var tempPosts = [Post]()
        }

                postsRef.observe(.value, with: { snapshot in

                    for child in snapshot.children {
                        if let childSnapshot = child as? DataSnapshot,
                            let data = childSnapshot.value as? [String:Any],
//                            let timestamp = data["timestamp"] as? Double,
                            let first_name = data["Author"] as? String,
                            let postTitle = data["title"] as? String,
                            let postDescription = data["description"] as? String,
                            let postUrl = data["postUrl"] as? String,
                            let postAddress = data["Address"] as? String,
                            let url = URL(string:postUrl)
                        {

                            // Convert timestamp to date
//                            let newDate = self.getDateFromTimeStamp(timestamp:timestamp)

                            // Store variables from DB into post
                            let post = Post(author: first_name, postTitle: postTitle, postDescription: postDescription, postUrl: url, postAddress: postAddress)

                            test.tempPosts.append(post)

                        }
                    }

                    self.posts = test.tempPosts
                    // HERE IT WORKS
                    print(test.tempPosts[0].postTitle , " 0")
                    self.tableView.reloadData()

                })

        // HERE IT DOESN'T WORK
        print(test.tempPosts[0].postTitle , " 0")

    }

and I'm trying to access the data where it says: // HERE IT DOESN'T WORK, how can I access that array outside of it? I need to call it later

Arturo
  • 3,254
  • 2
  • 22
  • 61

1 Answers1

0

The observe() method is asynchronous, so after you call postsRef.observe the code executed within that closure is run ONLY AFTER the application receives a response from Firebase, so there's a delay. All code after this call that's NOT stored within the closure will be executed immediately though.

So the .observe asynchronous function call is executed, and then the next line under // HERE IT DOESN'T WORK is executed immediately after. This is why this doesn't work because test.tempPosts doesn't contain any values until after the server response is received, and by that time, your print statement outside the closure has already run.

Check out this StackOverflow answer to get some more information about async vs sync.

Asynchronous vs synchronous execution, what does it really mean?

Also too, you may want to look into closures on Swift here.

If you want to access the value outside of the closure, you'll need to look into using a completion handler or a class property.

Edit: Here's an example

func observe (finished: @escaping ([Post]) -> Void) {
    // ALL YOUR CODE...

    finished(test.tempPosts)
}

func getTempPosts () {
    observe( (tempPosts) in
        print(tempPosts)
    }
}
adeiji
  • 550
  • 1
  • 3
  • 13
  • I tried declering the function like this: `func observe(finished: () -> Void) {` and then when the asynchronous method finishes, call `finished()` but it doesn't work, it says: `Escaping closure captures non-escaping parameter 'finished'` – Arturo Nov 13 '19 at 02:54
  • Add @escaping before finished param, this basically says that after the function has finished, preserve this closure. Doing a Google search on escaping closure would be good. – adeiji Nov 13 '19 at 03:38
  • I'm sorry, you need to put it after finished, so like this (finished: @escaping () -> Void) – adeiji Nov 13 '19 at 03:54
  • Ok, now it works, but how do I access let's say the array tempPosts after it finishes on another function? – Arturo Nov 13 '19 at 04:00