performSegueWithIdentifier outside of viewDidAppear not working - ios

I am sure this is a beginners question, but I am trying to perform a Segue if the users of my application are logged into Facebook, or if they do in the initial screen. In the viewDidAppear function, I test if they are already logged in, and if they are, the segue works just fine. But in my other function, is does absolutely nothing (not even an error).
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if (PFUser.currentUser() == nil) {
//...//
} else {
print("User already logged in")
self.performSegueWithIdentifier("mainMenuSegue", sender: self) // This one is Working
}}
func logInViewController(logInController: PFLogInViewController, didLogInUser user: PFUser) -> Void {
print("We just logged you in!")
if PFUser.currentUser()!["First_Name"] == nil {
returnUserData() } else {
print(NSThread.isMainThread()) //Returning True
self.performSegueWithIdentifier("mainMenuSegue", sender: self)// This one is NOT Working
}
}
What am I doing wrong?

In iOS 6 and later it´s possible: You have to implement the method in the controller and return true or false
if you return false segue will fail to goto destination.
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
in swift
override func shouldPerformSegueWithIdentifier(identifier: String!, sender: AnyObject!) -> Bool {
//todo
}

Related

Swift Firebase: how to check user is verified after send email?

After creating account i sending an email with verification link:
func sendVerificationMail() {
if self.authUser != nil && !self.authUser!.isEmailVerified {
self.authUser!.sendEmailVerification(completion: { (error) in
// TODO Notify user email was sent or not because of error
})
} else {
// TODO Notify everything is OK
}
}
And in other place i checking it confirmed:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if Auth.auth().currentUser != nil && Auth.auth().currentUser!.isEmailVerified {
self.performSegue(withIdentifier: "toMainScreen", sender: self)
} else {
self.performSegue(withIdentifier: "notLoggedView", sender: self)
}
}
Even if confirmed, i always go to notLoggedView. Somebody can explain why?
I have faced the similar issue and to solve it I have to reload the profile. Try this.
func loginUser() {
Auth.auth().currentUser?.reload(completion: { (error) in
if let error = error {
print(error)
} else {
if Auth.auth().currentUser != nil && Auth.auth().currentUser!.isEmailVerified {
self.performSegue(withIdentifier: "toMainScreen", sender: self)
} else {
self.performSegue(withIdentifier: "notLoggedView", sender: self).
}
}
})
}
Also, instead of writing Auth.auth().currentUser every time you can store that in a variable. And, you can use this function wherever you want.
if let authUser = Auth.auth().currentUser { //You can also get current user like this in a safe way
//Do your stuff here
}

iOS Firebase - how to check if user not logged in

I wan't to check if the user is't logged into my app.
If that happend, i wan't to redirect him to notLoggedView or verifyAccuontView.
At this moment code looks like this and if user not created i can't get into notLoggedView.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true);
let user = Auth.auth().currentUser;
if (user == nil) {
self.performSegue(withIdentifier: "notLoggedView", sender: self);
}
}
This code works same as above (like user exist, but firebase accounts is empty)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true);
if let user = Auth.auth().currentUser {
// action when account exist
} else {
self.performSegue(withIdentifier: "notLoggedView", sender: self);
}
}
override func viewDidLoad() {
super.viewDidLoad()
Auth.auth()!.addStateDidChangeListener() { auth, user in
if user != nil {
self.switchStoryboard()
}
}
}
or You can check directly
if Auth.auth().currentUser?.uid != nil {
//user is logged in
}else{
//user is not logged in
}
for Signup you use
Auth.auth().createUser(withEmail: emailField.text!, password: passwordField.text!) { user, error in
if error == nil {
// 3
Auth.auth().signIn(withEmail: self.textFieldLoginEmail.text!,
password: self.textFieldLoginPassword.text!)
}
}
If you want to check if there is no user logged in, check currentUser directly.
let user = Auth.auth().currentUser;
if (user == nil) {
// there is no user signed in when user is nil
}
Also be sure see the documentation for more information.

What to use between performsegue and shouldperformsegue to execute segue if only the condition is TRUE

I am having a hard time in solving my own issue regarding segue. The scenario should be when the user tapped the backbutton it will prompt an alert which will ask the user Are you sure to leave this page? Leave or Stay are the option. If the user tapped Leave response, it will go back to the DashBoard and if the user tapped Stay it will just retain to its original ViewController. The problem is the segue automatically executes without checking the condition inside the backbutton. I am new in swift and all issues I encountered and encountering are very new to me. How will I construct my codes correctly to meet the requirements of the backbutton. How will the button executes first the condition before it performs segue? Hope you can help me. Below are my codes for your reference. Been here for almost 1 week. Thank you.
performSegue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDashBoard" {
if let dashBoardVC = segue.destination as? DashBoardViewController {
dashBoardVC.validPincode = validPincode
dashBoardVC.participants = participants
dashBoardVC.event = event
}
}
}
backbutton
#IBAction func backbutton(_ sender: UIButton) {
let alert = SCLAlertView(appearance: confirmationAppearance)
_ = alert.addButton("Leave", action: {
self.dismiss(animated: true, completion: nil)
self.performSegue(withIdentifier: "showDashBoard", sender: sender)
})
_ = alert.addButton("Stay", action: { })
_ = alert.showError("Confirmation", subTitle: "Are you sure you want to leave this page?")
}
trying to use shouldPerformSegue but I don't know how to start
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "showDashBoard" {
var segueShouldOccur: Bool!
if segueShouldOccur == false {
print("nope, user wants to stay")
return false
}
else {
self.performSegue(withIdentifier: "showDashBoard", sender: sender)
print("Yep, the user wants to leave")
}
}
return true
}
screencapture for storyboard segue
For the benefit of someone who's like me, newbie in using swift. I solved my own issue. I omitted the segue connected between the back buttonand DashBoard. I transfer the segue from ParticipantsViewController going to DashBoardViewController.:)
#IBAction func backbutton(_ sender: UIButton) {
let alert = SCLAlertView(appearance: confirmationAppearance)
_ = alert.addButton("Leave", action: {
self.dismiss(animated: true, completion: {
self.performSegue(withIdentifier: "showDashBoard", sender: sender)
})
})
_ = alert.addButton("Stay", action: { })
_ = alert.showError("Confirmation", subTitle: "Are you sure you want to leave this page?")
}

Swift segue not working?

My Swift segue is not working at all and isn't throwing any errors. The breakpoint shows me that the app lands on this line but nothing happens:
self.performSegueWithIdentifier("SignupSegue", sender: self)
The code block is a login form with Facebook:
if let accessToken: FBSDKAccessToken = FBSDKAccessToken.currentAccessToken() {
PFFacebookUtils.logInInBackgroundWithAccessToken(result.token, block: {
(user: PFUser ? , error : NSError ? ) - > Void in
if user!.isNew {
self.performSegueWithIdentifier("SignupSegue", sender: self)
} else {
self.navigateToInGame(true)
}
})
}
Here's the segue function it should call, but doesn't even get to it:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier == "SignupSegue") {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("SignUpViewController")
self.showViewController(vc, sender: self)
}
}
Any ideas?
Generally, any UI updating has to be in main thread. I think the block for PFFacebookUtils.logInInBackgroundWithAccessToken is still in the background state in above situation. Maybe trigger the showViewController in dispatch_async(dispatch_get_main_queue(), {}) and see if there is any difference.
dispatch_async(dispatch_get_main_queue(), {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("SignUpViewController")
self.showViewController(vc, sender: self)
})
Ok. I just tried it out. Hope you did all the things regarding StoryBoard Reference.
Me too had the same issue with performSegueWithIdentifier.
Example:
Let take two storyboard main and signup.
1) In main.storyboard create a storyboard reference. Set the storyboardId in the Storyboard Reference as signup and the referencedId as the storyboardId of the scene(viewController) which is in signup.storyboard. Look at this link for a clear picture Storyboard to Storyboard
2) Set the segue identifier between viewController and Storyboard Reference in main.storyboard
3) Since I faced the same problem with performSegueWithIdentifier, I replaced it with shouldPerformSegueWithIdentifier.
override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
if(identifier == "segue_identifier"){
// segue_identifier is the viewController and storyBoard Reference segue identifier.
print("hello")
}
return true;
}
Let me know if you find any issues. It did work for me.
Performing a segue leads to present a new view controller.You don't need to and can't create and show view controller in prepareForSegue.It will look like:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier == "SignupSegue") {
let vc = segue.destinationViewController
}
}
Swift 3 solved:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "SignupSegue") {
DispatchQueue.main.async {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "SignUpViewController")
self.show(vc, sender: self)
}
}
}
You can try this ...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier == "SignupSegue") {
if let destination = segue.destination as? SignUpViewController {
...
}
}
}
The closest I can get to overcome same problem for myself:
Made trigger var segueLogin : Bool = false with initialised value in the Class.
When PFFacebookUtils gets needed values for segue, change trigger to true:
PFFacebookUtils.logInInBackground(withReadPermissions: permissions) {
(user: PFUser?, error: Error?) -> Void in
if let user = user {
if user.isNew {
print("User signed up and logged in through Facebook!")
self.segueLogin = true
} else {
print("User logged in through Facebook!")
self.segueLogin = true
}
} else {
print("Uh oh. The user cancelled the Facebook login.")
self.loginCancelledLabel.alpha = 1
}
}
Then added code to viewDidAppear class. Realised it starts everytime PFFacebookUtils complete. So it checks if returned value is true and performs segue after successful PFFacebookUtils session:
override func viewDidAppear(_ animated: Bool) {
if segueLogin == true {
self.performSegue(withIdentifier: "segueSingup", sender: self)
}
}

Segues not executing when run using Swift and Parse

So I've set up my app to determine if there is a user and what to do if there is or is not. Also if they have verified their account (via phone number and sms) my issue is that when I run the app nothing happens. It loads and then just doesn't perform any of the segues. All segue identifiers are named correctly. currentUser variable has a value but numberIsVerified has no value. Im sure that has something to do with it but not sure what or how to fix it.
Code to determine where to take the user:
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
var currentUser = PFUser.currentUser()
if currentUser == nil || currentUser!["phoneNumberVerified"] == nil {
performSegueWithIdentifier("showInitialView", sender: self)
} else {
if let numberIsVerified = currentUser!["phoneNumberVerified"] as? Bool {
if currentUser != nil && numberIsVerified == false {
performSegueWithIdentifier("showVerifyUserView", sender: self)
} else if currentUser != nil && numberIsVerified == true {
performSegueWithIdentifier("showMyEventsView", sender: self)
} else {
performSegueWithIdentifier("showInitialView", sender: self)
}
}
}
}
}
You can only use performSegueWithIdentifier when your view is fully loaded. So you can't segue from viewDidLoad. To fix this, move your segue to viewDidAppear:
override func viewDidAppear(animated: Bool) {
}
update: i created a simple application that performs the segue for you to compare your code to:
download project

Resources