Reputation: 15
I am new to IOS programming and don't really know what I'm asking but I will try and explain
I am using Firebase
to auth and then I want to take the UID and pass it to a different VC the problem I am getting I cant get the var userID
to print out side of the IBAction
here is where I am so far, any pointer would get good cheers guys
@IBAction func creatAccountPressed(_ sender: Any) {
if let email = emailTextField.text,
let password = passwordTextField.text,
let name = nameTextField.text {
Auth.auth().createUser(withEmail: email, password: password, completion: { user, error in
if let firebaseError = error {
print(firebaseError.localizedDescription)
}
let userID = user!.uid
let userEmail: String = self.emailTextField.text!
let fullName: String = self.nameTextField.text!
self.ref.child("users").child(userID).setValue(["Email": userEmail, "Name": fullName])
self.userID1 = user!.uid as! String
})
print(self.userID1)
presentLoggedInScreen()
}
}
func presentLoggedInScreen() {
let stroyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let loggedInVC: LoggedInVCViewController = stroyboard.instantiateViewController(withIdentifier: "loggedInVC") as! LoggedInVCViewController
self.present(loggedInVC, animated: true, completion: nil)
}
Upvotes: 1
Views: 2872
Reputation: 1090
One the simpler way to pass info from one VC to another is either through an initiliazer, or through a variable that you set before presenting the second VC.
Since you are new to this, try the variable approach for now, so if say, you're passing a string:
class LoggedInVCViewController : UIViewController {
var info : String? {
didSet {
if let newInfo = self.info {
//do what ever you need to do here
}
}
}
override viewDidLoad() {
super.viewDidLoad()
}
}
func presentLoggedInScreen(yourInfo: String) {
let stroyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let loggedInVC:LoggedInVCViewController =
storyboard.instantiateViewController(withIdentifier: "loggedInVC") as!
LoggedInVCViewController
loggedInVC.info = yourInfo
self.present(loggedInVC, animated: true, completion: nil)
}
Mind you, you can always use any other king of variable Class for info
. You also would program your VC to execute some methods inside of the get bracket of the property, populate some fields based on the content of info, load a specific UI etc.
Another usefull way is to go the initialization route, but unfortunately you cannot use it with Storyboard nibs (sad i know, but this post goes over this nicely), but it still usefull whenever you will feel comfortable enough to initialize and design VC's programmatically (which I would learn ASAP if were you).
You pass a variable in a custom intializer method for your VC:
class LoggedInVCViewController : UIViewController {
var info : Any? {
get {
if let this = self.info {
return this
} else {
return nil
}
} set {
if let new = newValue {
//
}
}
}
init(info: Any?) {
//This first line is key, it also calls viewDidLoad() internally, so don't re-write viewDidLoad() here!!
super.init(nibName: nil, bundle: nil)
if let newInfo = info {
//here we check info for whatever you pass to it
self.info = newInfo
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
So you would use is as:
func presentLoggedInScreen(yourInfo: String) {
let loggedInVC = LoggedInVCViewController(info: yourInfo)
self.present(loggedInVC, animated: true, completion: nil)
}
Obviously, as stated, this method cannot be used with Storyboards, but very usefull and, as I'm sure you can see, is much more compact.
I suggest you get familiar with Swift Properties of the docs, along with some blog tips such as this one. You can get pretty creative after a while.
For learning more programmatic approaches, i strongly recommend this YouTube channel: Let's Build That App, I personnaly haven't found a better reference point for programmatic approach Swift programming.
Don't hesitate to ask questions!
UPDATE
Your IBAction should look like this:
@IBAction func creatAccountPressed(_ sender: Any) {
if let email = emailTextField.text, let password = passwordTextField.text, let name = nameTextField.text {
Auth.auth().createUser(withEmail: email, password: password, completion: { user, error in
if let firebaseError = error {
print(firebaseError.localizedDescription)
}
let userID = user!.uid
let userEmail: String = self.emailTextField.text!
let fullName: String = self.nameTextField.text!
self.ref.child("users").child(userID).setValue(["Email": userEmail, "Name": fullName])
self.userID1 = user!.uid as! String
print(self.userID1)
presentLoggedInScreen(yourInfo: self.userID1)
})
}
}
Upvotes: 2
Reputation: 4729
Put
print(self.userID1)
presentLoggedInScreen()
inside the completion block. Currently those lines are almost certain to happen before the completion block is done as the block is executed after the required network calls return.
Be sure to wrap presentLoggedInScreen()
in a block that dispatches it to the main thread as it touches the UI and all UI calls must be made from the main thread.
DispatchQueue.main.async {
presentLoggedInScreen()
}
This will make it so that presentLoggedInScreen()
executes after the value as been assigned to userID1
allowing you to pass the value over to the incoming view controller (assuming, of course, that the incoming VC has an appropriate variable to pass userID1
into).
Something like:
loggedInVC.userID = self.userID1
before you present the VC.
Upvotes: 0