iOS

Login and User registration tutorial using Swift

Introduction

This section explains how you can create an app with a simple user registration using Parse Server core features through Back4App.

This is how it will look like:

User Registration App

At any time, you can access the complete iOS Project built with this tutorial at our GitHub repository.

Prerequisites

To complete this tutorial, you need:

Step 1 - Set up

  1. Add another view controller called LoggedInViewController.swift. In the main storyboard drag a view controller on to the canvas and set the class to LoggedInViewController and set the Storyboard ID to LoggedInViewController

  2. In both ViewController.swift and LoggedInViewController.swift make sure to include the Parse module by including it at the top of the file.

    1
    import Parse
    

Step 2 - Create your Sign Up and Login UI

Logging in creates a Session object, which points to the User logged in. If login is successful, ParseUser.CurrentUser() returns a User object, and a Session object is created in the Dashboard. Otherwise, if the target username does not exist, or the password is wrong, it returns null.

The method used to perform the login action is ParseUser.logInWithUsername(), which requires as many arguments as the strings of username and password, and may call a callback function.

Note: After signing up, login is performed automatically.

  1. Drag four UITextFields onto the ViewController in the main storyboard. Center the textfield and put two at the top and two at the bottom of the view controller. Drag two more UIButtons on to the view and place them below the textfields. Set the top button text to say Sign In. Set the bottom bottom to say Sign Up. Set the text fields to say username and password. It should look like this.

User Registration App

  1. Next we are going to connect your UITextFields in your storyboard to properties in your view controller. Add the following properties to the top of ViewController.swift. Next go to your storyboard and right click on each UITextField and click on the reference outlet then drag a line back to the ViewController icon and set it to the appropriate field. signInUsernameField connects to the sign In Username Field, etc… ViewController.swift
    1
    2
    3
    4
     @IBOutlet fileprivate var signInUsernameField: UITextField!
     @IBOutlet fileprivate var signInPasswordField: UITextField!
     @IBOutlet fileprivate var signUpUsernameField: UITextField!
     @IBOutlet fileprivate var signUpPasswordField: UITextField!
    
  2. Then in the viewDidLoad method set all of the UITextFields to an empty character to avoid crashes. ViewController.swift
    1
    2
    3
    4
    5
    6
    7
     override func viewDidLoad() {
         super.viewDidLoad()
         signInUsernameField.text = ""
         signInPasswordField.text = ""
         signUpUsernameField.text = ""
         signUpPasswordField.text = ""
     }
    
  3. Then in the viewDidAppear method check to see if you are already logged in. If you are logged in you will redirect the user to the LoggedInViewController. ViewController.swift
    1
    2
    3
    4
    5
    6
     override func viewDidAppear(_ animated: Bool) {
         let currentUser = PFUser.current()
         if currentUser != nil {
             loadHomeScreen()
         }
     }
    
  4. Next lets add the loadHomeScreen method. It will redirec the user to the LoggedInViewController. Make sure the that the LoggedInViewController in the storyboard has its class and Storyboard ID set to LoggedInViewController. ViewController.swift
    1
    2
    3
    4
    5
     func loadHomeScreen(){
         let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
         let loggedInViewController = storyBoard.instantiateViewController(withIdentifier: "LoggedInViewController") as! LoggedInViewController
         self.present(loggedInViewController, animated: true, completion: nil)
     }
    
  5. Next lets create an extension file to handle our activity spinner to show when network activity is occurring. Since we will use the spinner in multiple places an extension is the best place to put this code. Create a file called Extensions.swift and put the following code inside of it. Extensions.swift
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    extension UIViewController {
     class func displaySpinner(onView : UIView) -> UIView {
         let spinnerView = UIView.init(frame: onView.bounds)
         spinnerView.backgroundColor = UIColor.init(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)
         let ai = UIActivityIndicatorView.init(activityIndicatorStyle: .whiteLarge)
         ai.startAnimating()
         ai.center = spinnerView.center
    
         DispatchQueue.main.async {
             spinnerView.addSubview(ai)
             onView.addSubview(spinnerView)
         }
    
         return spinnerView
     }
    
     class func removeSpinner(spinner :UIView) {
         DispatchQueue.main.async {
             spinner.removeFromSuperview()
         }
     }
    }
    
  6. Now that we can handle network activity lets set up the IBAction that will connect to the SignUp button on the ViewController in the main storyboard. ViewController.swift
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     @IBAction func signUp(_ sender: UIButton) {
         let user = PFUser()
         user.username = signUpUsernameField.text
         user.password = signUpPasswordField.text
         let sv = UIViewController.displaySpinner(onView: self.view)
         user.signUpInBackground { (success, error) in
             UIViewController.removeSpinner(spinner: sv)
             if success{
                 self.loadHomeScreen()
             }else{
                 if let descrip = error?.localizedDescription{
                     self.displayErrorMessage(message: descrip)
                 }
             }
         }
     }
    
  7. We need to add the displayErrorMessage function to show any error messages from the server. We will use this method anytime we communicate with our parse app. ViewController.swift
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     func displayErrorMessage(message:String) {
         let alertView = UIAlertController(title: "Error!", message: message, preferredStyle: .alert)
         let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction) in
         }
         alertView.addAction(OKAction)
         if let presenter = alertView.popoverPresentationController {
             presenter.sourceView = self.view
             presenter.sourceRect = self.view.bounds
         }
         self.present(alertView, animated: true, completion:nil)
     }
    
  8. Now that we can handle network activity and network errors lets set up the IBAction that will connect to the SignIn button on the ViewController in the main storyboard. ViewController.swift
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     @IBAction func signIn(_ sender: UIButton) {
         let sv = UIViewController.displaySpinner(onView: self.view)
         PFUser.logInWithUsername(inBackground: signInUsernameField.text!, password: signInPasswordField.text!) { (user, error) in
             UIViewController.removeSpinner(spinner: sv)
             if user != nil {
                 self.loadHomeScreen()
             }else{
                 if let descrip = error?.localizedDescription{
                     self.displayErrorMessage(message: (descrip))
                 }
             }
         }
     }
    

Step 3 - Log Out

Logging out deletes the active Session object for the logged User. The method used to perform log out is ParseUser.logOutInBackground().

  1. Drag a UIButton on to LoggedInViewController in the main storyboard. Set the button title to ‘Logout’. It should look like this.

User Registration App

  1. Lets add the displayErrorMessage function again to show any error messages from the server. We will use this method anytime we communicate with our parse app. LoggedInViewController.swift
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     func displayErrorMessage(message:String) {
         let alertView = UIAlertController(title: "Error!", message: message, preferredStyle: .alert)
         let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction) in
         }
         alertView.addAction(OKAction)
         if let presenter = alertView.popoverPresentationController {
             presenter.sourceView = self.view
             presenter.sourceRect = self.view.bounds
         }
         self.present(alertView, animated: true, completion:nil)
     }
    
  2. Lets add the loadLoginScreen function to take us back to the login/signup screen after we logout. LoggedInViewController.swift
    1
    2
    3
    4
    5
     func loadLoginScreen(){
         let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
         let viewController = storyBoard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
         self.present(viewController, animated: true, completion: nil)
     }
    
  3. Finally lets add the IBAction to execute the logout call and take us back to ViewController.swift signup/login page. This method logs out the PFUser and takes you back to the signup page. Connect this IBAction to the logout button on LoggedInViewController. LoggedInViewController.swift
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     @IBAction func logoutOfApp(_ sender: UIButton) {
         let sv = UIViewController.displaySpinner(onView: self.view)
         PFUser.logOutInBackground { (error: Error?) in
             UIViewController.removeSpinner(spinner: sv)
             if (error == nil){
                 self.loadLoginScreen()
             }else{
                 if let descrip = error?.localizedDescription{
                     self.displayMessage(message: descrip)
                 }else{
                     self.displayMessage(message: "error logging out")
                 }
    
             }
         }
     }
    

Step 4 - Test your app

  1. Run your app and create a couple of users, also try logging in again after registering them.
  2. Login at Back4App Website.
  3. Find your app and click on Dashboard > Core > Browser > User.
  4. Try logging in and out with the same user and signing back in.

At this point, you should see your users as displayed below:

Parse Dashboard

Note: Using the codes displayed above, every time you log in with a user, a Session is opened in your Dashboard, but when the user logs out that particular Session ends. Also, whenever an unsuccessful login or sign up attempt occurs, the Session opened in Parse Server Dashboard is deleted.

It’s done!

At this stage, you can log in, register or log out of your app using Parse Server core features through Back4App!