I am working on an iOS app that logs the user in by a Login View.
There are two controllers: LognViewController and SignUpViewController If a new user signs up instead, then the Sign Up View Controller makes an API call to retrieve a new user account. Then, the Sign Up page should transfer the new User object back to the Login page, which in turn logs the user in to the main app.
Based on a previous post I like the idea of a closure, and I'm trying to implement it here; however, I'm getting a nil on the closure function variable. My code is something like this:
In the First Controller:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "userSignUp" {
if !self.userTextField.text!.isEmpty {
let nav = segue.destinationViewController as! UINavigationController
let vc = nav.topViewController as! SignUpViewController
vc.email = self.userTextField.text!
vc.submitUser = signUpToLogIn
}
}
}
// asynchronous get user back from sign up
func signUpToLogIn(currentUser: User) {
self.currentUser = currentUser
self.checkCurrentUser()
}
In the Second Controller:
var submitUser: ((currentUser: User) -> ())!
@IBAction func signUpButtonTapped(sender: UIButton) {
doSignUp({(u: User?) -> () in
if u != nil {
self.submitUser(currentUser: u!)
self.dismissViewControllerAnimated(false, completion: nil)
}
})
}
I'm looking at the debugger, and it says fatal error: unexpectedly found nil while unwrapping an Optional value When I work with a breakpoint, I can see in the variables section that the submitUser variable is always nil.
Is there a different way of doing this now?
Instead of passing a closure, can you use delegation instead? Your SignUpViewController
can notify your LoginViewController
when a new user has signed up and pass the new User
object back through a delegate method like so
Signup View Controller:
protocol SignUpDelegate {
func userDidSignUp(u: User)
}
class SignUpViewController: UIViewController {
var delegate: SignUpDelegate?
@IBAction func signUpButtonTapped(sender: UIButton) {
// Make async call to sign new user up here
// Once you get a User back from your API call your delegate
// method in your completion or at the end of your network call
self.delegate?.userDidSignUp(newUserObject)
self.dismissViewControllerAnimated(false, completion: nil)
}
}
Then in your login view controller you can implement this delegate method
Login view controller:
class LoginViewController: UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "userSignUp" {
if !self.userTextField.text!.isEmpty {
let nav = segue.destinationViewController as! UINavigationController
let vc = nav.topViewController as! SignUpViewController
vc.email = self.userTextField.text!
vc.delegate = self
}
}
}
// MARK: SignUpDelegate
func userDidSignUp(u: User) {
// Log user in with new user
}
}
Inside the @IBAction func signUpButtonTapped(sender: UIButton)
:
Try using this function to do the transition to another view controller:
[self performSegueWithIdentifier:@"segueIdentifierHere" sender:self];
Don't forget to remove the self.dismissViewController
function you are currently using before you try the performSegueWithIdentifier
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.