pprevalon pprevalon - 3 months ago 16
Swift Question

using variables outside of completion block

Im currently retrieving data from firebase the data is put inside an

NSObject
and then a completion block. The item inside of the completion block is store as a variable
userBinfos
. Variable
userBinfos
only work inside of the completion block i want to use this outside of the completion

var userBinfos = userObject()
override func viewDidLoad() {
super.viewDidLoad()

userBinfo { (user) in
self.userBinfos = user

}
//I want to use to variable here but it does not work
print(self.userBinfos.email)

}


func userBinfo(completion: (userObject) -> ()) {

let dbFir = FIRDatabase.database().reference()

let firRef = dbFir.child("frontEnd/users/\(userId)")

firRef.observeEventType(.Value, withBlock: { snapshot in

let userDict = snapshot.value as! [String: AnyObject]
self.name.text = userDict["firstname"] as? String
self.userBio.text = userDict["userBio"] as! String

var user = userObject()

user.firstName = userDict["firstname"]
user.lastName = userDict["lastname"]
user.email = userDict["email"]
user.profileImageUrl = userDict["profileImageUrl"]
user.userBio = userDict["firstname"]
user.userId = userDict["firstname"]

dispatch_async(dispatch_get_main_queue(), {
completion(user)

})

}) { (error) in
print(error)
}

}

Rob Rob
Answer

The entire purpose of the completion parameter of userBinfo is to provide a mechanism for being informed when the asynchronous observeEventType is called. So put code contingent upon the completion of that asynchronous method inside the userBinfo { user in ... } closure.

And if part of the UI doesn't make sense until that asynchronous completion closure is called, then have viewDidLoad configure the UI to make that explicit (perhaps show a UIActivityIndicatorView or whatever) and then remove that stuff inside the completion handler.

override func viewDidLoad() {
    super.viewDidLoad()

    // do whatever you want to let the user know that something asynchronous
    // is happening, e.g. add a spinning `UIActivityIndicatorView` or whatever

    userBinfo { user in
        self.userBinfos = user

        // Update the UI here, including removing anything we presented to let
        // the user know that the asynchronous process was underway. If you were
        // dealing with UITableView`, you'd call `tableView.reloadData()` here.
    }  

    // but not here
}
Comments