iOS + Swift + parse.com — How to implement email verification of users

iOS 8.3+
Swift 1.2
Parse 1.7.2

How to make sure our user really exists*

*Maybe

You’ll find links to the solutions and other resources at the end of this tutorial.

One of the great feature sets that Parse provides are user management capabilities. You are able to choose which elements of the user sign up and sign in processes you will manage directly and which you will have Parse manage on your behalf. For beginners this alone is a reason to use the platform.

My personal preference is to create my own interface objects for the sign up and sign in workflows and use Parse to provide the backend check/tests/mechanics. In this tutorial we’ll take our existing Swift/Parse app (that already has Sign Up and Sign In features) and extend it to include Email Verification.

It’s worth looking over the workflow that we’re going to be implementing.

Looks complex? Truth is that managing users is one of the most complex elements of any application — mobile/web/executable — and is fraught with pitfalls that could end up compromising your users, your data and even your business. @TroyHunt has a great tutorial series over on Pluralsight that I recommend you checking out.

Seeing as we already have a partial Sign Up and Sign In workflow we have much already in place — we’ll only need to add the ORANGE elements to complete the email verification features. Do not be fooled — the workflow we will be implementing is not a complete workflow. I have cut out many steps that would need to be implemented in the real world just to make this tutorial manageable.

We’ll finish up considering what to do with legacy users.

Goal

Let’s take a look at what we’re going to achieve.

The key functional capabilities we’re aiming for are:

  • Allow users to sign up
  • Send a verification email
  • Tell the user to check their email inbox
  • Check verification at sign in

Strategy

We’re going to achieve the new email verification feature via 5 simple steps.

  • Download the starter project from GitHub
  • Enable email verification on the parse.com platform
  • Add a SignOut() method to the Sign Up / In view controller
  • Display “check your email” message when a user signs up
  • Implement an email verification check when users sign in

Step 1 — Download the starter project

So that we’re all starting from the same point there is a tutorial starter project over on GitHub. Let’s start by downloading a copy and checking that the project builds — if that’s successful then Hurrah!

Step 2 — Enable email verification on the parse.com platform

When you create a new application over on parse.com the default behaviour is that email verification emails are NOT sent to users as they sign up.

Let’s sign in to Parse.com and adjust this setting — Click “Settings” in the top tab bar and then click “Email” in the side tab bar.

Slide the “Verify user emails” Yes/No switch so that it is set to Yes.

Thats it. Email verification is now enabled to all new users.

Note : The Email verification value CAN NOT be manually set within the parse.com web application — it can only be set by the user when they click the email verification link.

The Email settings area also provides options regarding how your emails will be addressed and the design and layout of your emails. It’s worth spending time on this settings page to customise exactly how your emails will appear.

Note : Email verification can not “flick of the switch” be enabled for users already signed up to your app. We will pick this point up later in the tutorial.

Step 3 — Add a Sign Out method

When a user signs up to our app the parse.com platform returns a valid PFUser() object. Depending on how we handle the sign up process it is possible that this will also sign the user in to our app, bypassing any email verification process.

We’ll update our app so that when a user signs up they are then immediately signed out which will allow us to enforce the email verification flow.

Add the following method to the SignUpInViewController.swift.

The new method is pretty simple so I’ll not step through the code.

We’ll use this method in the next step.

Step 4 — Display “check your email” message

The next step is to adjust the existing sign up flow so that users are presented a “we have sent you an email message” and then returned to the SignUpIn view controller.

Within SignUpInViewController.swift. Update the processSignUp() method to the following.

I’m not going to step through ALL the processSignUp() method code — I’ll focus on the key changes we’ve just made.

Lets dive into this segment.

user.signUpInBackgroundWithBlock { (succeeded: Bool, error: NSError?) -> Void in 
if error == nil {
// User needs to verify email address before continuing let
alertController = UIAlertController(
title: "Email address verification",
message: "We have sent you an email that contains a link - you must click this link before you can continue.",
preferredStyle: UIAlertControllerStyle.Alert
)
alertController.addAction(UIAlertAction(
title: "OKAY",
style: UIAlertActionStyle.Default,
handler: {
alertController in self.processSignOut()
}
)
)
// Display alert self.presentViewController(
alertController,
animated: true,
completion: nil
)
} else {
self.activityIndicator.stopAnimating()
if let message: AnyObject = error!.userInfo!["error"] {
self.message.text = "\(message)"
}
}
}

This segment calls the parse signUpInBackgroundWithBlock method, processing the code in the block upon a response from the parse.com platform.

if error == nil {

If there is no error…

// User needs to verify email address before continuing let    
alertController = UIAlertController(
title: "Email address verification",
message: "We have sent you an email that contains a link - you must click this link before you can continue.",
preferredStyle: UIAlertControllerStyle.Alert
)
alertController.addAction(UIAlertAction(
title: "OKAY",
style: UIAlertActionStyle.Default,
handler: {
alertController in self.processSignOut()
}
)
)
// Display alert self.presentViewController(
alertController,
animated: true,
completion: nil
)

Present an alert controller to the user. The message tells the user that they need to click a link in an email they’ve been sent. The alert controller has a single OKAY button that when clicked the processSignOut() method is called.

Step 5 — Check verification at sign in

Within SignUpInViewController.swift. Update the signIn() method to this new code.

Like the sign up code we’ll not discuss all of it in detail.

PFUser.logInWithUsernameInBackground( 
userEmailAddress,
password:userPassword
) { (user: PFUser?, error: NSError?) -> Void in
if user != nil {
// Check that the user has verified their email address
if user!["emailVerified"] as! Bool == true {
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier(
"signInToNavigation",
sender: self
)
}
} else {
// User needs to verify email address before continuing
let alertController = UIAlertController(
title: "Email address verification",
message: "We have sent you an email that contains a link - you must click this link before you can continue.",
preferredStyle: UIAlertControllerStyle.Alert
)
alertController.addAction(
UIAlertAction(
title: "OKAY",
style: UIAlertActionStyle.Default,
handler: { alertController in self.processSignOut()}
)
)
// Display alert self.presentViewController(
alertController, animated:
true, completion: nil
)
}
}

Let’s focus on the key elements of this segment.

if user != nil { 

If the user successfully signed in.

if user[“emailVerified”] as! Bool == true {    
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier(
“signInToNavigation”,
sender: self
)
}

And if they have verified their email address then segue to the main view controller.

} else {

Present an alert controller telling that they need to check their email inbox for an email and to click the link contained. The alert controller only has one button which calls the processSignOut() method.

Users created before email verification was enabled

It is possible that you have some users that were created before you enabled the email verification workflow, in which case you have 2 candidate routes to select from.

You could adjust the test if user[“emailVerified”] as! Bool == true to take into account that these “non verified” users will not have a completed ‘emailVerified’ property — as an optional this property will be nil. Personally I think this is a kludge and does not deliver on why you’re implementing email verification in the first place — presumably to confirm you can contact the user.

The second — and better — route would be to bring the user into the email verification process. This is easily achieved by re-saving the users email address, which will prompt the Parse platform to send a verification email.

In case you need it — here is a Gist that provides an example signIn() method that brings pre-verified-users into the verification process. https://gist.github.com/Bizzi-Body/c78ce859755c1054c72d

Currently the parse.com platform is requiring the email address on the server to be changed before an verification email is sent. This means that right now you will need to set the email address to something that NO USERS have access to and then update and re-save the user record using the correct email address. Right now it is not clear if this is a bug or a new feature — hopefully it is just a bug and will be corrected.

Congratulations

You’ve achieved implementing email verification for your app users.

Links

Parse
Parse XCode framework download page
Troy Hunt — Twitter
Pluralsight — Secure Account Management / Troy Hunt
GitHub source for starter project
GitHub source for completed solution


Originally published at bizzi-body.com/blog on May 17, 2015.