Parse switching view controller on successful login - ios

After the user logs in SUCCESSFULLY, I need to switch view controllers to the timeline section of my app, this is also going to be a tab bar view controller with 5 different tabs at the bottom. Here is the code I have so far, it works and is connected to the parse database I have setup.
import UIKit
import Parse
class LoginViewController: UIViewController {
#IBOutlet var usernameField: UITextField!
#IBOutlet var passwordField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func loginTapped(sender: AnyObject) {
let username = usernameField.text
let password = passwordField.text
PFUser.logInWithUsernameInBackground(username, password:password) {
(user: PFUser?, error: NSError?) -> Void in
if user != nil {
println("Success")
} else {
var loginError:UIAlertView = UIAlertView(title: "Invalid Login", message: "I did not recognize your credentials. Try again?", delegate: self, cancelButtonTitle: "Dismiss")
loginError.show()
}
}
}
#IBAction func closeTapped(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
}
In the line println("sucessful"), instead of printing out the sucessful login I need to switch to their timeline home (the tab bar view controller).

Use a segue to transition to new view controller if the login was successful:
if user != nil {
self.performSegueWithIdentifier("successfulLoginPage", sender: self)
}

Related

Closing and opening my app goes straight to homepage without verifying the user email

When I create a new user it does everything it should do and saves the users detail and goes back to the login page waiting for the email to be verified before allowing it to be used. The coding works so it doesn't allowing you to proceed until email has been verified but I've realised when I slide the app to close it and then reopen it (before verifying the email), it goes straight to the homepage bypassing the login page even if the email hasn't been verified?
import UIKit
import Firebase
import SwiftKeychainWrapper
class ViewController: UIViewController {
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
var userUid: String!
override func viewDidLoad(){
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(_ animated: Bool) {
func Keychain() {
KeychainWrapper.standard.set(userUid, forKey: "uid")
}
if let _ = KeychainWrapper.standard.string(forKey: "uid"){
LoggedIn()
}
}
func goToCreateUserVC() {
performSegue(withIdentifier: "CreateAProfile", sender: nil)
}
func LoggedIn() {
performSegue(withIdentifier: "LoginSuccessful", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "CreateAProfile" {
if let destination = segue.destination as? CreatUsers {
if userUid != nil {
destination.userUid = userUid
}
if emailField.text != nil {
destination.emailField = emailField.text
}
if passwordField.text != nil {
destination.passwordField = passwordField.text
}
}
}
}
func DisplayAlertMessage(MessageToDisplay: String) {
let alertController = UIAlertController(title: "Alert", message: MessageToDisplay, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in
// Code in this block will trigger when OK button tapped.
print("Ok button tapped");
}
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion:nil)
}
#IBAction func signIntapped(_ sender: Any) {
if let email = emailField.text, let password = passwordField.text {
Auth.auth().signIn(withEmail: email, password: password, completion:
{(user,error) in
if let user = Auth.auth().currentUser {
if user.isEmailVerified {
self.userUid = user.uid
print("Email Verified")
self.LoggedIn()
} else {
self.DisplayAlertMessage(MessageToDisplay: "Need To Verify Email Address")
}
} else {
self.DisplayAlertMessage(MessageToDisplay: "Incorrect Username/Password")
}
});
}
}
#IBAction func NotaMemberisTapped(_ sender: Any) {
self.goToCreateUserVC()
}
}
Only happens when I close the app and reopen it to find it cheats its way through - trying to figure out how to prevent it from happening.
You’re calling your LoggedIn() function based on whether or not there is a value in the keychain. I’m assuming you’re saving that information to the keychain whether or not validation has been performed.

data not showing up in firebase database

im attempting to add user data via a create account view controller which contains all UITextFields (password, confirm password, first name, last name, phone number). when the create account button is tapped, the users email shows up in the authentication section on the firebase website but the user information from the first name, last name and phone number text fields are not passed into the database. I'm new to iOS development and have never used firebase so im unsure what the issue is. the app runs without crashing.
below is my Create Account view controller
thanks in advance
import UIKit
import FirebaseAuth
import QuartzCore
import FirebaseDatabase
import Firebase
class CreateAccount: UIViewController {
var refUsers: DatabaseReference!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
#IBOutlet weak var confirmPasswordTextField: UITextField!
#IBOutlet weak var firstNameTextField: UITextField!
#IBOutlet weak var lastNameTextField: UITextField!
#IBOutlet weak var phoneNumberTextField: UITextField!
#IBOutlet weak var alreadyHaveAccountLabel: UILabel!
#IBAction func loginButtonTapped(_ sender: Any) {
performSegue(withIdentifier: "showLoginScreen", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.refUsers = Database.database().reference().child("Users");
// Do any additional setup after loading the view.
}
override func viewDidAppear(_ animated: Bool) {
if Auth.auth().currentUser != nil {
print("success")
self.presentMainScreen()
}
}
#IBAction func createAccountTapped(_ sender: Any) {
if let email = emailTextField.text, let password = passwordTextField.text {
Auth.auth().createUser(withEmail: email, password: password, completion:{ user, error in
if let firebaseError = error {
print(firebaseError.localizedDescription)
return
} else {
self.addUser()
print("this is the first name:", self.firstNameTextField.text!)
print("this is the last name:", self.lastNameTextField.text!)
print("this is the phone number" , self.phoneNumberTextField.text!)
print("success")
self.presentMainScreen()
}
})
}
}
func addUser(){
let key = refUsers.childByAutoId().key
let user = ["id":key,
"FirstName":firstNameTextField.text! as String,
"LastName":lastNameTextField.text! as String,
"PhoneNumber":phoneNumberTextField.text! as String
]
refUsers.child(key).setValue(user)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
func presentMainScreen(){
let mainstoryboard = UIStoryboard(name: "Main", bundle: nil)
let mainTabController = mainstoryboard.instantiateViewController(withIdentifier: "MainTabController") as! MainTabController
mainTabController.selectedViewController = mainTabController.viewControllers?[0]
self.present(mainTabController, animated: true, completion: nil)
//let storyboard:UIStoryboard = UIStoryboard(name:"Main", bundle:nil)
//let loggedInVC:LoggedInVC = storyboard.instantiateViewController(withIdentifier: "LoggedInVC") as! LoggedInVC
//self.present(loggedInVC, animated: true, completion: nil)
}
}
Try this:
Instead of set value use update value
let childUpdates = ["/user/\(key)": user]
refUser.updateChildValues(childUpdates)
Hope this helps :)

crashing: _finishDecodingLayoutGuideConnections:] unrecognized selector sent to instance

I am working in X-code 9 beta Swift 4, and can run and build but get the following error and only a white screen loads:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[myapp.logInVC _finishDecodingLayoutGuideConnections:]: unrecognized selector sent to instance 0x10251ead0'
Not sure what _finishDecodingLayoutGuideConnections is?
I checked all my selectors, but didn't see an issue. This is a login screen using Firebase, and my hope would be if login is successful it will load the View Controller.
Any help would be much appreciated!
class logInVC: UIViewController {
#IBOutlet weak var signInSelector: UISegmentedControl!
#IBOutlet weak var signInLabel: UILabel!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
var isSignIn:Bool = true
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func signInSelectorChanged(_ sender: UISegmentedControl) {
switch signInSelector.selectedSegmentIndex
{
case 0:
signInLabel.text = "sign in";
case 1:
signInLabel.text = "create account";
default:
break
}
}
#IBAction func signInButtonTapped(_ sender: UIButton) {
if isSignIn {
//validation
if let email = emailTextField.text, let pass = passwordTextField.text
{
//sign in with Firebase
Auth.auth().signIn(withEmail: email, password: pass) { (user, error) in
// make sure user isn't nil
if user != nil {
//user is found, go to AR experience
self.performSegue(withIdentifier: "goToHome" , sender: self)
}
else {
//error, check error and show message
}
}
}
else {
//register with Firebase
Auth.auth().createUser(withEmail: emailTextField.text!, password: passwordTextField.text!) { (user, error) in
// make sure user isn't nil
if user != nil {
//user is found, go to AR experience
self.performSegue(withIdentifier: "goToHome" , sender: self)
}
else {
//error, check error, and show message
}
}
Check whether your IBOutlets and IBActions are properly connected. The error occurs when your XiB and Class files are not properly setup.

How do I add a sign up page into my Parse app with Swift?

Dose anyone know how I can make a user sign up with parse in Swift Xcode 6.4?
I Have searched everything and can't find one that works.
I Tried this code but it did not work.
It said:
Use of unresolved identifier PFUser
import UIKit
class SignupViewController: UIViewController {
#IBOutlet var usernameTextField: UITextField!
#IBOutlet var passwordTextField: UITextField!
#IBOutlet var emailTextField: UITextField!
#IBOutlet var messageLabel: UILabel!
#IBAction func loginVerifyButton(sender: AnyObject) {
var usrEntered = usernameTextField.text
var pwdEntered = passwordTextField.text
var emlEntered = emailTextField.text
if usrEntered != "" && pwdEntered != "" && emlEntered != "" {
// If not empty then yay, do something
} else {
WrongInfo()
}
}
func userSignUp() {
var user = PFUser()
user.username = usrEntered
user.password = pwdEntered
user.email = emlEntered
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
func WrongInfo(){
var WrongInfo:UIAlertView = UIAlertView(title: "ALL FEILDS REQUIRED", message: "Please use all feilds!", delegate: self, cancelButtonTitle: "ok")
}
}
You need to import Parse , in Appdelegate.swift file! if still getting same error import Parse in signup view controller too
You have to create your own view and then implement it/segue users to it based on the users current status. If they click your sign up button segue them to a custom view and then act accordingly. You would sign them up with a function similar to what you have offered already in your question:
func myMethod() {
var user = PFUser()
user.username = "myUsername"
user.password = "myPassword"
user.email = "email#example.com"
// other fields can be set just like with PFObject
user["phone"] = "415-392-0202"
user.signUpInBackgroundWithBlock {
(succeeded: Bool, error: NSError?) -> Void in
if let error = error {
let errorString = error.userInfo?["error"] as? NSString
// Show the errorString somewhere and let the user try again.
} else {
// Hooray! Let them use the app now.
}
}
You essentially could use the same view you already have since your fields are identical but call different methods depending on the button they select.

Swift - Dismissing Alert Message Closes View Controller

I have a registration process where I have an entry point with a Login/register with Facebook (Connected to Parse). If the user has never registered with their Facebook account, then they are sent to a send page where a user registers a username, email and password. I have a function setup that if a user leaves any of the text fields blank for the user registration, then a alert message appears with an error stating the field is blank. This functionality works correctly, but when I click "OK" to dismiss the message, the registration view controller dismisses itself and the entry point (login screen) view controller is displayed. This should not be happening and I don't have a segue setup to go from registration screen to login screen. Any thoughts?
One thing that pops out to me is the error in the console log, which I believe is actually associated with the Parse if/else statement, and not with the field == nil statement.
Console Log:
2015-04-14 10:42:56.293 tappery[574:142525] [Error]: missing username (Code: 200, Version: 1.6.3)
Login Screen View Controller:
import UIKit
class LoginViewController: UIViewController {
#IBOutlet var loginCancelledLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var currentUser = PFUser.currentUser()
if currentUser != nil {
println("User is Logged in")
} else {
println("User is not logged in")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func facebookLoginButton(sender: AnyObject) {
var permissions = ["public_profile", "email", "user_friends"]
self.loginCancelledLabel.alpha = 0
PFFacebookUtils.logInWithPermissions(permissions, {
(user: PFUser!, error: NSError!) -> Void in
if let user = user {
if user.isNew {
println("User signed up and logged in through Facebook!")
self.performSegueWithIdentifier("registerUser", sender: self)
} else {
println("User logged in through Facebook!")
self.performSegueWithIdentifier("loginSuccessful", sender: self)
}
} else {
println("Uh oh. The user cancelled the Facebook login.")
self.loginCancelledLabel.alpha = 1
}
})
}
}
Registration View Controller:
import UIKit
class UserRegistrationViewController: UIViewController {
func displayAlert(title:String, error:String) {
var alert = UIAlertController(title: title, message: error, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: {
action in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
#IBOutlet var usernameTextField: UITextField!
#IBOutlet var emailTextField: UITextField!
#IBOutlet var passwordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func registerUser(sender: AnyObject) {
var error = ""
if usernameTextField.text == nil || emailTextField.text == nil || passwordTextField.text == nil {
error = "Please enter a username, email and password"
}
if error != "" {
displayAlert("Error In Form", error: error)
} else {
var user = PFUser.currentUser()
user.username = usernameTextField.text
user.password = passwordTextField.text
user.email = emailTextField.text
user.saveInBackgroundWithBlock {
(succeeded: Bool!, signupError: NSError!) -> Void in
if signupError == nil {
println(user.username)
println(user.password)
println(user.email)
self.performSegueWithIdentifier("successfulRegistration", sender: self)
// Hooray! Let them use the app now.
} else {
if let errorString = signupError.userInfo?["error"] as? NSString {
error = errorString
} else {
error = "Please try again later."
}
self.displayAlert("Could Not Sign Up", error: error)
}
}
}
}
Remove self.dismissViewControllerAnimated(true, completion: nil) from your OK button UIAlertAction's handler. Alert is dismissed automatically upon OK button click and you're dismissing registration controller with this call.

Resources