This is a guest tutorial by Rumiya Murtazina. Some time ago, we’ve discussed with you how to integrate your iOS app with Parse and demonstrate how to build an Instagram-like app using the service. Not only can you use Parse to save data, the service provides a PFUser class to manage your app’s user information. In this tutorial, Rumiya will show you how to build a simple login app and walk you through the procedures to store user credentials in Parse cloud.
Enter Rumiya’s tutorial.
Parse is a third party “cloud app solution” that is platform independent. You can learn more about it here. This intermediate programming tutorial will show you how to incorporate Parse into a Swift project and store user login details in Parse cloud storage.
Getting Started
I’ve prepared a project template that includes the Storyboard and View controller classes. You will find the Login, Sign Up, Reset Password and Home scenes already designed.
Running the project should present you with a simple user profile home screen. Before we begin, take a few minutes to familiarize yourself with the project template.
Adding the Parse Framework
First, login to your Parse account or sign up for a free account. Go to your Dashboard and click “Create a new App”. Name your app “ParseDemo” and click “Create”.
Next, at the bottom of the widget, select “Quickstart Guide”. In the successive screens choose the following options: Data > Mobile > iOS > Swift — Existing Project.

Now you should be ready to follow the “Install the SDK” steps. Add the Parse framework and the listed libraries to your app’s Frameworks group.

We need to initialize Parse. This is done by importing the Parse and Bolts frameworks and updating the AppDelegate.swift file with the QuickStart generated code like this:
1 2 3 4 5 6 7 8 9 10 11 12 |
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { Parse.enableLocalDatastore() // Initialize Parse. Parse.setApplicationId("OzyfQlVF5pHLA0OmRHB0RKsfXpdWwGWJ1mYgDTI6", clientKey: "f7Jw2X4XzSW0whm2aDtYl7wdIYn5hZVvHuPJ72zu") // [Optional] Track statistics around application opens. PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions) return true } |
Please remember to replace the application ID and client key to yours. You can find these keys under the Settings tab of your Parse dashboard.
Make sure to import Parse at the top of each of the following classes:
- LoginViewController.swift
- HomeViewController.swift
- SignUpViewController.swift
- ResetPasswordViewController.swift
Now, compile and run. Your iOS app should be running with no errors in Xcode.
Displaying the Login Screen
An app user has to login or sign up before navigating to the user’s profile home screen. If the current visitor is not logged in, we need to bring up the login screen.
In the HomeViewController.swift file insert the following method to instantiate the Login View Controller with the Storyboard Id “Login”:
1 2 3 4 5 6 7 8 9 |
override func viewWillAppear(animated: Bool) { if (PFUser.currentUser() == nil) { dispatch_async(dispatch_get_main_queue(), { () -> Void in let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Login") as! UIViewController self.presentViewController(viewController, animated: true, completion: nil) }) } } |
Compile and run the project. Launching the app should bring up the login screen. We don’t have any registered users yet. We need to be able to navigate to the sign up screen to register a user.
Sign Up
To display the Sign Up screen got to the Storyboard, select the Sign Up button of the Login View Controller. Control-drag from the selected button to the Sign Up View Controller. When prompted, select the “present modally” option under selection segue.

In SignUpViewController.swift declare the following outlet variables for the email, username and password text fields:
1 2 3 |
@IBOutlet weak var emailField: UITextField! @IBOutlet weak var usernameField: UITextField! @IBOutlet weak var passwordField: UITextField! |
Next, insert the following code to create the action method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
@IBAction func signUpAction(sender: AnyObject) { var username = self.usernameField.text var password = self.passwordField.text var email = self.emailField.text var finalEmail = email.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) // Validate the text fields if count(username) < 5 { var alert = UIAlertView(title: "Invalid", message: "Username must be greater than 5 characters", delegate: self, cancelButtonTitle: "OK") alert.show() } else if count(password) < 8 { var alert = UIAlertView(title: "Invalid", message: "Password must be greater than 8 characters", delegate: self, cancelButtonTitle: "OK") alert.show() } else if count(email) < 8 { var alert = UIAlertView(title: "Invalid", message: "Please enter a valid email address", delegate: self, cancelButtonTitle: "OK") alert.show() } else { // Run a spinner to show a task in progress var spinner: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(0, 0, 150, 150)) as UIActivityIndicatorView spinner.startAnimating() var newUser = PFUser() newUser.username = username newUser.password = password newUser.email = finalEmail // Sign up the user asynchronously newUser.signUpInBackgroundWithBlock({ (succeed, error) -> Void in // Stop the spinner spinner.stopAnimating() if ((error) != nil) { var alert = UIAlertView(title: "Error", message: "\(error)", delegate: self, cancelButtonTitle: "OK") alert.show() } else { var alert = UIAlertView(title: "Success", message: "Signed Up", delegate: self, cancelButtonTitle: "OK") alert.show() dispatch_async(dispatch_get_main_queue(), { () -> Void in let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Home") as! UIViewController self.presentViewController(viewController, animated: true, completion: nil) }) } }) } } |
This action method is triggered when a user taps the Sign Up button. It perform a simple validation of the text fields values. If the validation is successful, the action method calls the signUpInBackgroundWithBlock Parse method. The signUpInBackgroundWithBlock method may take some time to finish because it is executed asynchronously. The spinner shows the task is in progress. Once the task is completed, a message will inform the user if the registration was successful or not. If the registration is successful, the user will be logged in and navigated to the home screen.
Now, go back to the Storyboard and select the Sign Up View Controller. In the Connection Inspector connect each of the outlet variables to the corresponding text fields.

Next, select the Sign Up button. In the Connection Inspector connect the Touch Up Inside event with the Sign Up button. When prompted, select signUpAction: option.

In order to dismiss the sign up screen we need to define an unwind segue. Go to LoginViewController.swift, and insert this unwind action:
1 2 |
@IBAction func unwindToLogInScreen(segue:UIStoryboardSegue) { } |
In the Storyboard, select the Sign Up View Controller and control-drag from the close button to the exit icon. When prompted, select the “unwindToHome:” option under action segue.

Compile and run. Now you should be able to register a user.
Go to your Parse account, select Core for your ParseDemo app. Select the User section to see the first registered user:

Login and Log out
Now let’s move onto the implementation of login and logout. In LoginViewController.swift declare the following outlet variables for the username and password text fields:
1 2 |
@IBOutlet weak var usernameField: UITextField! @IBOutlet weak var passwordField: UITextField! |
Next, insert the following action method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
@IBAction func loginAction(sender: AnyObject) { var username = self.usernameField.text var password = self.passwordField.text // Validate the text fields if count(username) < 5 { var alert = UIAlertView(title: "Invalid", message: "Username must be greater than 5 characters", delegate: self, cancelButtonTitle: "OK") alert.show() } else if count(password) < 8 { var alert = UIAlertView(title: "Invalid", message: "Password must be greater than 8 characters", delegate: self, cancelButtonTitle: "OK") alert.show() } else { // Run a spinner to show a task in progress var spinner: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(0, 0, 150, 150)) as UIActivityIndicatorView spinner.startAnimating() // Send a request to login PFUser.logInWithUsernameInBackground(username, password: password, block: { (user, error) -> Void in // Stop the spinner spinner.stopAnimating() if ((user) != nil) { var alert = UIAlertView(title: "Success", message: "Logged In", delegate: self, cancelButtonTitle: "OK") alert.show() dispatch_async(dispatch_get_main_queue(), { () -> Void in let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Home") as! UIViewController self.presentViewController(viewController, animated: true, completion: nil) }) } else { var alert = UIAlertView(title: "Error", message: "\(error)", delegate: self, cancelButtonTitle: "OK") alert.show() } }) } } |
The above code is triggered when a user taps the Login button. It’s similar to the one we implemented in the SignUpViewController.swift. Except, instead of calling the signUpInBackgroundWithBlock method, we call logInWithUsernameInBackground to pass the entered username and password to Parse. If the login is successful the Home View Controller with the Storyboard Id “Home” will be instantiated.
Now, in the Storyboard, connect the Login View Controller outlet variables to the corresponding text fields. Select the Login button. In the Connection Inspector connect the Touch Up Inside event with the Login button. When prompted, select “loginAction:” option.
For a user to be able to log out, we need to implement the logOutAction action method in HomeViewController.swift:
1 2 3 4 5 6 7 8 9 10 11 |
@IBAction func logOutAction(sender: AnyObject){ // Send a request to log out a user PFUser.logOut() dispatch_async(dispatch_get_main_queue(), { () -> Void in let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Login") as! UIViewController self.presentViewController(viewController, animated: true, completion: nil) }) } |
The code calls the logOut Parse method and instantiates the Login scene.
In the Storyboard select the Logout button. In the Connection Inspector connect the Touch Up Inside event with the Login button. When prompted, select “logOutAction:” option.
There is one more thing to do before we test this part. The following steps are for replacing the text “user name” with the actual username (think about that for a minute). Let’s declare an outlet variable for the Username label in the HomeViewController.swift file:
1 |
@IBOutlet weak var userNameLabel: UILabel! |
Update the viewDidLoad method with the following code:
1 2 3 4 5 6 7 8 |
override func viewDidLoad() { super.viewDidLoad() // Show the current visitor's username if let pUserName = PFUser.currentUser()?["username"] as? String { self.userNameLabel.text = "@" + pUserName } } |
Go back to the Storyboard and connect the userNameLabel outlet variable to the corresponding User Name label in the Home View Controller.
Compile and run. The home screen will show the current username.

Reset Password
In ResetPasswordViewController.swift declare the outlet variable for the Email text field:
1 |
@IBOutlet weak var emailField: UITextField! |
Next, insert the following action method:
1 2 3 4 5 6 7 8 9 10 11 |
@IBAction func passwordReset(sender: AnyObject) { var email = self.emailField.text var finalEmail = email.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) // Send a request to reset a password PFUser.requestPasswordResetForEmailInBackground(finalEmail) var alert = UIAlertController (title: "Password Reset", message: "An email containing information on how to reset your password has been sent to " + finalEmail + ".", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } |
Here we just call the requestPasswordResetForEmailInBackground method with the specified email to reset the password. The password reset will then be handled by Parse. If the email is valid, an email will be sent to that address with instructions on how to reset their password.
The process of setting the ResetPasswordViewController in the Storyboard should be familiar to you by now. Set up a segue from the login screen, connect the outlet variable with the text field, and the action method with the button. Don’t forget to unwind the close button.

And there you have it! For your reference, you can download the complete Xcode project here. Just remember to update AppDelegate.swift with your Parse application keys.
Don’t stop here, there is so much more to do. Try figuring out how to validate the email text field properly. The user doesn’t have a profile picture. Implement a feature to upload and save a profile picture. Add an option to login with Facebook.
As you can see Parse does a lot of the heavy lifting for you, leaving you to concentrate on making a beautiful and useful application. Play around with it and happy coding!
This tutorial is contributed by Rumiya. Rumiya is an independent iOS developer. Over her career she has worn many hats from IT technical support, to Visual FoxPro database ninja (that’s a really old hat), to web developer. She’s recently fallen in love with Swift after finishing Appcoda’s book. Rumiya firmly believes that the best way to improve her programming chops is to learn a new topic and write a tutorial about it. She chronicles her app developing adventures at abearablecode.com. Rumiya’s non-coding activities include painting, drawing, photography and blogging about a wide variety of tasty projects at elegantpantry.me.
Comments
Jordi Gámez
AuthorThanks for sharing this information, I was trying to make a Login and a Register platform and now with this example using Parse it’s going to be so easy to finally achieve this feature in my App. Much appreciated.
Rumiya Murtazina
AuthorThat’s great!
Adnan
AuthorNice tutorial .Login,Signup buttons hide under keyboard as keyboard hidden functionality is unavailable in tutorial code. it would be good to add below method in every viewController.swift to have a user friendly demo .
override func touchesBegan(touches: Set, withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
self.view.endEditing(true)
super.touchesBegan(touches , withEvent:event)
}
}
Simon Ng
AuthorThanks for the sharing. That’ll definitely make the demo even better.
shaideru
AuthorI am following your tutorial using swift2 & xcode7beta5. In the validation part, count(username) < 5 doesn't work, I replaced it with this line
if username?.characters.count < 5
Awesome tutorial by the way! Thanks!
EntreGuy
AuthorThis doesn’t seem to work with Swift 2 and Xcode 7.1 beta. I am getting all kinds of build errors around SQL Lite…
Frederick
AuthorNice, great tut on how to get started
James Hartley
AuthorAny chance of updating this for iOS 9? Lots of errors.
Sense Luo
Authorif you are using Swift 2, you should change “count(username)” to “username!.characters.count”
Zardoz
AuthorThank you. That’s just the correction I needed lo these 9 months later.
Bhavin Chauhan
Authorit’s very use full tutorial for me, Thanks, Appcoda team.
William Muñoz Rodas
AuthorNice tutorial. I am creating an app and I am using Core Data for storing the information. But when I saw this tutorial I started to explore Parse and I created a procedure that when the user press sync button on Settings I copy all the new records or apply updates (including deletes) to Parse database, I am doing it because I am developing (trying…) an Android app too, so if the user will change his/her phone can download the application from Google Play and authenticate with Parse and download his/her information, or probably use the application from two devices (iPhone and Android). I wonder if you can give me advice if what I am doing is correct or Parse is not for this kind of solution. Or if you can suggest me another solution to accomplish this.
Richard Isabellas-Daddy Grey
AuthorHi is there anyway to add the enter button to the keyboard so you can press enter to submit
fairly newbie
asinox
AuthorHello, nice tut!, i thinking I’m having an issue, i can’t see the spinner… any light about it?
Thank!
Dane Jordan
AuthorYou have to add the spinner to the view:
self.view.addSubview(spinner)
You’ll have to mess with the spinner frame accordingly to get it where you want.
Jordan
AuthorI’m getting a “Only instance properties can be declared @IBOutlet” error and the email, username, passwordField variables are not showing up to connect to their respective fields. I’m also getting a “Use of resolved identifier ‘self’ error. All of this after adding the blurb at the beginning of the Sign Up section. Has anyone else come across this scenario?
yikaraman
AuthorThis is really Nice Tutorial Thanks.
ahmed khanfir
AuthorReally nice tutorial! thanks! My first iOS app!… I updated some stuff :
1/ the use of count(myString) :
we should use myString?.characters.count
2/ as Adnan code didn’t work for me, to be able to hide the keyboard once we clicked outside, I added this method on each screen:
// I’ve just token Adnan code and updated it a bit. Thanks Adnan.
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
if let touch = touches.first {
self.view.endEditing(true)
super.touchesBegan(touches , withEvent:event)
}
}
soledad
AuthorThanks AppCoda.You always find ways to help us.
Madeline Coven
AuthorWhat a wonderful tutorial, and a godsend for a beginning developer like me. Unfortunately, it needs updating.
MikeH
AuthorII’m unable to connect “touch up inside” to the sign up button with the sign up view. For some reason I am able to connect to any of the username, password, or email text fields but the button is not an option.
Any ideas?
Nicholas Moignard
Authorrather than copying code and then dragging the connection
drag the connection from the button to the view controller, then set up the action within the pop up (remember to select Action from the drop down not Outlet).
Nicholas Moignard
AuthorSense Luo “if you are using Swift 2, you should change “count(username)” to “username!.characters.count””
use optional binding & chaining when pulling the text from the outlets rather than force unwrapping the string optionals.
works pretty well like so.
if let username = self.usernameField.text, password = self.passwordField.text, email = self.emailField.text { …
if username.characters.count < 5 {
…
}
}
EmreÖ
AuthorThanks for the tutorail. I’m creating my own app and i added signup and login VC’s. the problem is when the user login to the app, login vc never redirect to main vc. my main vc is tableVC, is there any changing for TableVC ?
thank you very much
EmreÖ
AuthorI was used UIAlertViewController, then when i disabled them, its working correctly!
which way i need to check errors?
ShaneN
AuthorHi very good tutorial, will defiantly be using some more of yours . However when I try to signup in the simulator I keep getting this error and cannot figure out where I went wrong or how I can fix it
fatal error: unexpectedly found nil while unwrapping an Optional value
on the line –
let username = self.usernameField.text (Thread1: EXC Bad_Instruction)
Any help would be greatly appreciated 🙁
Aymen BRomdhane
AuthorShould I have an account developper to run the final xcode project? it won’t work on my simulator?
raghu
Authorerror:you cannot signup without usename
while i giving username in objective c please solve this
nisha
Authorcould u please show us our ur main.storyboard looks
iosswift12
AuthorHi Simon, Great tutorial, I learned a lot from this project !!!
I am a newbie to programming and Swift. Can you please explain why you had to put presentviewVC calls inside dispatch_async(). I googled and kinda new it had something to do with multithreading. Some articles say that you should call dispatch_async() when trying to download data from the internet then parse json and stuff. But here, you just switching screens. Is that really necessary?
Thank you,
SSJWhite
AuthorHello, what if i have two versions of signup? 1 for customers and 1 for drivers, both having different screens/viewcontrollers.
koni
Authorhi i want name,address,mobile no and email textfields validations
Florian Marcu
AuthorThanks for sharing this great tutorial! Extremely detailed! I’d also recommend checking out this Login Screen written in Swift 4, which has support for Facebook Login as well.
oposaot
AuthorСпасибо за информацию!!!!!
ursulawhitty163
AuthorMy brother recommended I might like this blog. He was once totally right. This post truly made my day. You can not believe simply how a lot time I had spent for this information! Thank you!