Complete Guide to Validating Email Addresses in Swift

Last Updated Feb 13, 2022

Table of Contents:

Email validation can be a concept you might look past until you sign up on the web using an invalidly input email address and all the reply emails you’d eagerly wait for never reach you. 

Similarly, email address validation would be a crucial measure for the web service to maintain a good mailing list and lower their email bounce rates – and with that not-so-valid email address you just sent, you certainly weren’t helping them with their cause!

Moreover, IETF possessing the current IMF rules would tell you a valid email address isn’t quite as simple as <anything>@<something>.<another-thing>.

So, with its importance and the challenges it brings cleared out, let’s find out how we can validate email address input in Swift, shall we?

Don't reinvent the wheel.
Abstract's APIs are production-ready now.

Abstract's suite of API's are built to save you time. You don't need to be an expert in email validation, IP geolocation, etc. Just focus on writing code that's actually valuable for your app or business, and we'll handle the rest.

Get started for free

Three Methods to Validate Email in Swift

As much as with many other programming languages, Swift provides you with a range of options to validate email address inputs:

Using functions of Swift NSPredicate class to match an email address input with a regular expression.

  • RawRepresentable protocol

Creating a custom class conforming to RawRepresentable which initializes only if a valid email address is provided.

  • NSDataDetector

Utilizing Swift’s own “specialized regular expression object” to match valid email addresses.

Validate email address with a correct Regex and NSPredicate

Using NSPredicate, we can match a given string with an email validating regular expression.

Requirements

This option requires that we supply NSPredicate with a regular expression by ourselves. Hence, we could

  • write the email address validation regular expression from scratch – which admittedly could become quite agitating.
  • find a regular expression externally – where to grab regular expressions from? How reliable would the picked regular expressions be?

Risks

So, as you can see, although using NSPredicate with a regular expression could be called the easiest method from the rest, we would have to make sure to provide a correct regex to NSPredicate each time since it’d directly affect the accuracy of the validation.

As for another risk, since eventually NSPredicate evaluates and matches a simple Swift String, the string wouldn’t hold a sign on whether it’s been validated as an email address or not. In other words, an already validated email string could traverse your Swift app where you wouldn’t be able to tell straight away if it’s been validated when you spot it in another location.

Regex + NSPredicate email address validation code example


func isValidEmailAddr(strToValidate: String) -> Bool {
  let emailValidationRegex = "^[\\p{L}0-9!#$%&'*+\\/=?^_`{|}~-][\\p{L}0-9.!#$%&'*+\\/=?^_`{|}~-]{0,63}@[\\p{L}0-9-]+(?:\\.[\\p{L}0-9-]{2,7})*$"  // 1

  let emailValidationPredicate = NSPredicate(format: "SELF MATCHES %@", emailValidationRegex)  // 2

  return emailValidationPredicate.evaluate(with: strToValidate)  // 3
}

  1. Specify an emailValidationRegex constant holding the email verification regular expression.
  2. Call NSPredicate initializer passing in a format that matches the object being evaluated with a format specifier specified in “%@”. The previously defined emailValidationRegex constant is passed in as the second parameter. NSPredicate would parse in the emailValidationRegex as the value for the %@ format specifier in the first parameter. Returned NSPredicate object is stored in an emailValidationPredicate constant.
  3. Execute the evaluate method of emailValidationPredicate passing in strToValidate as an argument. The returned boolean would indicate the validity of the passed in strToValidate string as an email address.

RawRepresentable to validate an email address

To reach a step ahead from the risks we discussed for the previous method, we could get the help of Swift’s RawRepresentable protocol. RawRepresentable protocol holds a RawValue associated type which the protocol’s initializer asks us to provide at initialization time. 

Requirements

The aforesaid behavior of RawRepresentable provides us with a nice opportunity to define custom types conforming to RawRepresentable where we could place the email address validation logic within its initializer and only set the rawValue variable if the validation is successful. 

Risks

Since RawRepresentable simply assists with better organization of our email address validation logic — and doesn’t bring anything particularly related to email address validation to the table — this method holds the same regular expression-related risks as the last time.

RawRepresentable email address validation code example


struct EmailAddress: RawRepresentable { //1
  let rawValue: String
  let emailValidationRegex = "^[\\p{L}0-9!#$%&'*+\\/=?^_`{|}~-][\\p{L}0-9.!#$%&'*+\\/=?^_`{|}~-]{0,63}@[\\p{L}0-9-]+(?:\\.[\\p{L}0-9-]{2,7})*$"  // 2

  init?(rawValue: String) {
    let emailPredicate = NSPredicate(format: "SELF MATCHES %@", emailValidationRegex)  // 3

    let evalResult = emailPredicate.evaluate(with: rawValue)  // 4

    if evalResult == true {  // 5
      print(rawValue + " is a valid email address")
      self.rawValue = rawValue
      } else {
        print(rawValue + " is not a valid email address")
        return nil
      }
    }
}

  1. Define an EmailAddress custom type conforming to the RawRepresentable protocol.
  2. Create an emailValidationRegex constant holding a regular expression to match with valid email address input.
  3. Create an NSPredicate named emailPredicate with a format that’d match objects it evaluates with a format specifier in the placeholder “%@”. Pass emailValidationRegex as the second argument for the NPSPredicate initializer – this value would be used on the %@ format specifier placeholder.
  4. Validate email address by calling the emailPredicate’s evaluate method with the rawValue string holding the email address to be validated. Store the evaluation result in an evalResult constant.
  5. If a valid email address was found, set that successful rawValue string as the value for the current EmailAddress object’s rawValue constant. If the validation failed,  return a nil value. Now, this EmailAddress struct would only create objects holding valid email addresses.

NSDataDetector to find a valid email address

Why use self-scripted regular expressions or put faith on regular expressions grabbed from other sites when you could validate email address input using their very own regular expression-based methods?

Enter NSDataDetector, a class that holds a collection of APIs to execute various validations for a diverse set of use cases, e.g., links, dates, phone numbers, etc. And, as you’d see on NSDataDetector class’s API specification, NSDataDetector conforms to the NSRegularExpression class essentially making its validations regular expression-based.

While NSDataDetector doesn’t supply a straightforward way to match a valid email address, we can use its link CheckingType for our email address validation purposes.

NSDataDetector email address validation code example

First off, let’s add an empty validate function to carry our NSDataDetector email address validation logic:


func validate(strToValidate: String) -> Bool {}

Initial set up

Secondly, let us take the preliminary steps to have NSDataDetector match the strToValidate string as a valid email address. Add the following code inside the validate function:


let emailDetector = try? NSDataDetector(  // 1
  types: NSTextCheckingResult.CheckingType.link.rawValue
)

let rangeOfStrToValidate = NSRange(  // 2
  strToValidate.startIndex..strToValidate.endIndex,
  in: strToValidate
)

let matches = emailDetector?.matches(  // 3
  in: strToValidate,
  options: [],
  range: rangeOfStrToValidate
)

  1. Initialize an NSDataDetector with its CheckingType set to link. Save the returned object to an emailDetector constant.
  2. Create a rangeOfStrToValidate NSRange constant holding a half-open range from strToValidate string’s starting index to its ending index.
  3. Call the matches method in emailDetector passing in the strToValidate along with the range that needs to be matched by emailDetector. Store the result in a matches constant.

Make evaluations

Thirdly, it’s time to make the evaluations needed to figure out if strToValidate string does in fact hold an email address. Hence, add the following code within the validate function right below the previous lines:


guard matches?.count == 1 else {  // 1
  return false
}
let singleMatch = matches?.first

guard singleMatch?.range == rangeOfStrToValidate else {  // 2
  return false
}

guard singleMatch?.url?.scheme == "mailto" else {  // 3
  return false
}

return true

  1. Validate that only a single email address was matched from the strToValidate string.
  2. Make sure the whole strToValidate was matched by NSDataDetector.
  3. Affirm that NSDataDetector recognized strToValidate as an email address which would be indicated by the singleMatch object’s URL scheme being set to “mailto” by NSDataDetector.

Using Abstract API to validate an email address

Hence, we discussed various methods to validate email address input in Swift, but what if we told you the easiest, safest, and most secure strategy to validate email addresses could be to use an API?

Let us introduce you to Abstract's Email Validation and Verification API.

Along with their email address validation and verification services, thanks to their

  • collection of checks ranging from real-time MX & SMTP checks to typo and disposable/free email checks
  • privacy-friendly operations (GDPR, CCPA)
  • all of this bundled in a free-to-use package

there would hardly be a reason not to give Abstract API a try.

If you’re interested, you can also check out a list of the best email address validation APIs where we discern each of their pros and cons.

Verify and validate emails in seconds using Abstract's API.

Get started for free
Verify and validate emails in seconds using Abstract's API.
Get started