An app requires you to create a new iOS password and you proceed to type in your cat’s name, as you’ve done with every single site and app that you’ve ever used.

You already have an account with a website when you download its app. Your credentials autofill on web, but you can’t remember them when you try to log in on mobile.

An app requires that new iOS passwords contain at least 99 characters — with at least one letter, five non-sequential numbers and a prime number of punctuation symbols, excluding ! and *.

You keep leaving an app to check the two-step verification code text message it sent you, but can’t seem to remember the random string of characters each time you return.

As users, these types of scenarios make anyone see exceptionally vivid shades of red and perhaps utter equally colorful shades of blue. :]

As developers, this makes iOS password handling a balancing act: On one hand, it’s critical to make the login process as simple as possible; every password requirement you add will increase your users’ motivation to uninstall your app. At the same time, developers have a responsibility to help users stay secure; hackers and abusers stage never-ending attacks on activists, celebrities and John Q. Public.

While this tutorial requires very little coding on your end, it assumes that you have some familiarity with Xcode and Terminal.

Getting Started

Download the materials for this tutorial using the Download Materials button found at the top and bottom of this page. Unzip the UltraMotivator files and open UltraMotivator-starter/UltraMotivator.xcodeproj in Xcode. Then, build and run the starter app on your simulator.

Starter project login screen, sign-up screen, and sign-up error.

Starting on the login screen, tap the Sign Up button in the bottom-right corner to navigate to the sign-up page. Enter a username and password, then tap Sign Up. An Error dialog should pop up. In the app’s current state, you can’t yet log in because the app’s back end doesn’t yet exist.

Note: Even if you haven’t set your text field content types, iOS still may recognize your fields as login-related. It does so by analyzing your placeholders, UI elements and on-screen text. This means that, while iOS may automatically offer iOS password autofill, strong password generation or code autofill, this behavior isn’t guaranteed, so it’s best to put these features in place explicitly.

Sadly, unauthenticated users can’t access on-demand encouragement, so the starter app is rather uninspiring for now. But, lucky for them, you’re about to code their path to inspirational quotation enlightenment!

A Peek at the Web App

Switch back to Finder and navigate to UltraMotivator-starter ▸ Motivational-Server. This directory contains the server app that you’ll deploy to the web to get the iOS app up and running.

Like the iOS app, the server app is written in Swift using Vapor, a modern web framework for Swift. While you won’t cover the details of Vapor here, you can check out our Video Course and book if you’d like to learn more.

Take a moment to get a bird’s-eye view of the web app’s structure. Most notably, this includes:

For this tutorial, you’ll deploy your server app to Heroku, since it offers a quick, easy and free solution. If you don’t already have a Heroku account, sign up to create one at https://signup.heroku.com/. Make note of your password, because you’ll need it later.

Creating a Heroku App

In the upper right-hand corner, click the button labeled New, then select Create new app.

On the next screen, either enter a unique app name or leave the App name field blank. Then, choose the deployment region.

If you leave App name blank, Heroku will automatically generate a unique slug to identify the app for you. Whether you create a name or Heroku assigns you one, make note of your app name because you’ll need it later when configuring your app. Click Create app.

After creating your app, Heroku redirects you to your app’s page.

Select the Resources tab near the top of the page. Under the section entitled Add-ons, enter postgre and you’ll see an option for Heroku Postgres; select this option.

This takes you to one more screen that asks what type of database to provision.

Choose the Hobby Dev — Free Plan name. Click the Provision button, and Heroku will do the rest.

Once you’ve finished, the database will appear under the Resources tab, indicating that your web app has been successfully created.

Getting Your App’s Identifiers

Now that you’ve set up Heroku to host your web app, it’s time to share Ultra Motivator’s credentials between web and mobile. To do this, you’ll need to set up a two-way association between your iOS app and the web server.

Go to Identifiers ▸ App IDs and select the Add button. Enter an App ID Description, then scroll down to the App ID Suffix ▸ Explicit App ID section and create a Bundle ID; this will be your App ID. Scroll down to the App Services section and enable the Associated Domains and AutoFill Credential Provider services.

Scroll down and click Continue to save. On the summary page, you’re presented with next, confirm that Associated Domains and AutoFill Credential Provider are both enabled. Then, scroll to the bottom and click Register. You should then see a Registration Complete page confirming that you’ve successfully completed this step.

Make note of the Prefix in the app’s header information display, to the right of the ID icon. This is your Team ID.

Adding App Identifiers to the Web App (Locally)

Now, open Terminal and cd into UltraMotivator-starter/Motivational-Server. For example, if you’ve unzipped the UltraMotivator files onto your desktop, you can enter:

cd ~/Desktop/UltraMotivator-starter/Motivational-Server

This sets Motivational-Server — the directory containing the server app — as the working directory.

Within Motivational-Server, create a Public directory and then a nested .well-known directory within it by entering the terminal command:

mkdir -p Public/.well-known/

Then, while replacing with your Team ID and with your App ID, enter the following:

Note: The apps array can hold multiple “.” strings. This allows you to set up two-way associations between multiple iOS apps and a single domain.

It’s important to use the exact filename apple-app-site-association as iOS will be looking for a file with this precise name.

Switch to Finder and navigate to UltraMotivator-starter/Motivational-Server/Public/.well-known/apple-app-site-association. If you’re unable to see .well-known, use the shortcut Command+Shift+. to toggle hidden file visibility. Open the association file in a text editor to confirm that it contains the specified JSON.

Setting Up Heroku CLI

Now that your mobile app’s IDs are in place, you’ll upload these to your web app. To do this, you’ll need the help of Heroku’s command line interface tools — Heroku CLI.

You’ll need Homebrew to install Heroku CLI. If Homebrew isn’t already installed on your computer, install it by entering the following into Terminal:

Deploying the Server App

In Terminal, confirm that Motivational-Server is still your working directory. To do so, enter the command pwd for the full directory address. Then, enter these commands while replacing with the Heroku app name that you set earlier in the “Creating a Heroku App” section of this tutorial:

This pushes your master branch to your Heroku remotely. You’ll have to wait several minutes as everything builds.

Note: If Heroku’s current deployment stack version is incompatible with the community buildpack, the push will fail. The error message will tell you exactly what happened and how to fix it. For example, you might see a message telling you to enter the command:

heroku stack:set heroku-16 -a <your-application-name>

Follow the instructions in the error message, then repeat the push command.

Congrats! You’re now the proud owner of a website capable of recognizing your iOS app via apple-app-site-association file. You can view your apple-app-site-association file at https://[your domain]/.well-known/apple-app-site-association. You’ve conquered the first half of your two-way association: Take a moment to bask in the glory!

Open UltraMotivator in Xcode, select your target at the top of the left-hand Project navigator, and click on the General tab.

In the Identity section, set the Bundle Identifier to your App ID. In the Signing section, check Automatically manage signing, then select the Team associated with the app: Xcode should now generate a provisioning profile and signing certificate. Any errors on your General page should now vanish.

At the bottom of the page, add AuthenticationServices.framework to Linked Frameworks and Libraries. You’ll need AuthenticationServices to integrate iOS password autofill.

Next, click the Capabilities tab. Find the option for Associated Domains and switch it ON to activate this capability.

Now, click +, then add your Heroku app’s domain to the list using the following format:

Once again, check marks should appear — this time, confirming that you’ve added the autofill credential provider feature to both your App ID and entitlements file. It also confirms that you’ve included the AuthenticationServices.framework.

Putting It All Together

Phew! That’s a lot of micro steps! Happily, now it’s time to wire everything up. :]

Return to UltraMotivator.xcodeproj in Xcode, open API.swift and find the following code on line 46:

static let baseURL = URL(string: "https://[your domain]")

Replace “[your domain]” with the Heroku app name that you copied and used previously.

API.swift contains API calls capable of communicating with the server app at your domain. These calls help perform user log in, registration, log out, password changes and random motivational-quote generation. Most of these calls are already integrated into the iOS app. Now that you’ve added your domain, authentication should work as intended.

Select the Username field on the Login view controller. Open the Attributes inspector tab in the right-hand Inspector pane. Locate the Text Input Traits section and set Content Type to Username.

Now, select the Password field and set its Content Type to Password.

Similarly, on the Signup view controller, change the Username field’s Content Type to Username. Then, change the New Password field’s Content Type to New Password so that this field will now autofill a strong password suggestion.

Finally, open OneTimeCodeViewController.swift. Insert the following at line 42:

oneTimeCodeField.textContentType = .oneTimeCode

By setting textContentType to .oneTimeCode, whenever iOS detects a security code in an incoming message while the user is viewing this two-factor authentication screen, the QuickType bar above the keyboard will autofill with the code. The user will then be able to enter this code with a single tap, without ever leaving the app.

Customizing iOS Password AutoFill Rules

You’re almost there. Before taking on the final steps, you need to take a final quick detour to learn about iOS Password AutoFill rules.

Apple’s default suggested passwords are 20 characters long and must contain all of the following character types: uppercase, lowercase, digits and hyphens. This produces a strong password that’s compatible with most web services.

In some cases, though, you may need or want to set custom rules for the suggested iOS password. You can add these custom rules to the Password Rule property of any field in which Content Type is set to New Password.

required: Use “required” if the generated password must contain at least one member of the specified character class. To combine character classes, separate them with commas. For example, required: X, Y is equivalent to required: [XY] where X and Y represent character classes.

allowed: Use “allowed” if the restrictions specify a subset of allowed characters. If you don’t include the allowed property, and just include required, the password can only contain the required characters. If you only specify allowed and not required, then the password can only contain the characters that you’ve explicitly allowed. If you specify neither required or allowed, then your password can contain any ASCII printable characters.

max-consecutive: Follow “max-consecutive” with a positive integer to limit the number of times a character can appear consecutively.

minlength: Follow the “minlength” keyword with a positive integer to specify the minimum password length.

maxlength: Follow the “maxlength” keyword with a positive integer to specify the maximum password length.

You must use “allowed” and “required” alongside these permitted character classes:

upper: Represents uppercase letters A – Z.

lower: Represents lowercase letters a – z.

digit: Represents digits 0 – 9.

special: Includes -().&@?’#,/”+ and Space.

ascii-printable: Includes all ASCII characters.

unicode: Includes all unicode characters.

Or specify a custom character class by listing whichever ASCII characters that you’d like to include within square brackets. For example, “allowed: [a1,-]” allows characters “a”, “1”, “,” and “-“.

A Super Fun Happy Quiz? Oh, Boy!!

Think you get the gist? Try your hand at the following exercise. For each password rule, determine whether Password AutoFill can generate A, B, C and/or D. Each answer may consist of none|any|all of the multiple-choice options:

Congrats on getting through that exercise! That said, according to Apple:

The more restrictions you have on a password, the higher the likelihood that it can be guessed. The hardest-to-guess password rule is allowed: unicode. No password rule at all creates the second most-difficult-to-guess passwords.

So remember those complicated password rules you just painstakingly analyzed? As a general rule, you’ll usually want to avoid them when you can!

Putting Custom Password Rules to Use

That said, you took this quick detour for a very good reason. Whenever you’re integrating with a back end web service, chances are good that you’ll need to use iOS password rules to sync with any specific password requirements that service may impose.

For the sake of testing, imagine that your web back end:

Doesn’t accept special characters.

Needs to be at least 12 characters long.

Requires an uppercase character.

To meet those requirements, open Main.storyboard, select the New Password field in the Signup View Controller Scene, then copy and paste this password rule into New Password Field’s Password Rule field:

This rule requires at least one uppercase character; it also allows lowercase characters and digits; it generates a password 12 to 20 characters long, and it prevents any character from appearing more than three times consecutively.

As you go forward implementing your own iOS Password AutoFill rules, you can confirm that they work as intended by entering them into Apple’s Password Rules Validation Tool. There, you can review a few a hundred, or even ten thousand, generated passwords to make sure your rules produce the results you need.

Taking It for a Spin

You’ve now set up authentication, strong password autofill, security code autofill and custom iOS password rules. Build and run your iOS app to test it all on a physical iOS device — iOS Password AutoFill won’t work on a simulator.

Tap Sign Up on the bottom-right of the login page to navigate to the sign-up view.

The username field Keyboard Type is “E-mail Address”; so, while the Username field is the first responder, the QuickType bar may suggest email addresses that you’ve used to log in to other services. This is because iOS recognizes this particular username field as a sign-up username field.

After entering a username, select the Password field. It should autofill with a strong password that conforms to the rules that you specified in the field’s Password Rule. Tap Use Strong Password to use the autofill-provided suggestion, then tap Sign Up. An alert will pop up to let you know if you’ve registered successfully.

If you see the above alert, congrats! You’ve registered a new account. Tap OK and the sign-up view will dismiss itself to return to the login view.

Saving Your Passwords

There’s just one last piece of the puzzle: automatically saving your newly created credentials. As it turns out, for iOS to recognize that it needs to save a new set of credentials, you must:

Remove the Username and Password fields from the View hierarchy after sign up occurs.

Only clear the Username and Password fields after they’re no longer in the View hierarchy.

Since your app dismisses the sign-up view completely without deleting any fields, it already meets these requirements. Great! But how do you prevent your keychain from saving the credentials of a failed or incomplete sign-in attempt? Good question!

Open SignupViewController.swift, scroll down to viewWillDisappear(_:) and find this code snippet:

When a user signs up successfully, the server returns a token. UltraMotivator’s API.swift class stores this in the variable API.token.

If API.token is nil when the user navigates back to the login view, the sign-up action was not completed. In this case, you set the text fields to nil before leaving the View hierarchy, i.e., in viewWillDisappear(_:). This prevents these invalid credentials from being saved to the user’s keychain.

If API.token is not nil, the sign-up action has been completed successfully. In this case, you log out, leaving the fields’ text intact. iOS will then automatically save those credentials to the user’s keychain.

Checking Under the Hood

To confirm that your iOS password rules work, run the app on your iOS device (not a simulator) and sign up with a few different usernames. Open Keychain Access on your Mac. Select the login keychain, the Passwords category, then search your login passwords for your web app domain.

To view any of the passwords associated with your listed usernames, select it and tap the show password checkbox. Enter your keychain/computer password when prompted, and the password should appear.

According to my keychain, my usernames’ corresponding passwords are “rehnep0xasravezpUg”, “Qyddehziwzek2syhda” and “Qyddehziwzek2syhda.” All three of these conform to the custom password rules defined for the app.

To confirm that credentials aren’t saving when they shouldn’t, enter a username and password but press the Back button without signing up. Check Keychain Access’s login passwords once again to confirm that iOS didn’t save these invalid credentials to the keychain.

Once you’re satisfied that your credentials are saving as intended, return to your iOS device and attempt to log in to the app. Begin entering your username. Your username(s) should either appear in the QuickType bar automatically or after you tap the key symbol on its right side. Select your username and authenticate your keychain access using Touch ID, Face ID or device passcode when prompted. Your iOS password and username will autofill accordingly.

Submit those credentials and you should now see a two-step authentication screen:

Since two-step authentication is not set up on the back end, don’t wait for a code to automatically come through: You’ll have to test this feature manually.

To determine whether or not a text message contains a security code, iOS scans incoming texts for words like “code” or “passcode” with code string. So, to test this feature, keep Ultra Motivator open and text yourself via Apple’s desktop Messages app. Send yourself a code: “Your code is 1234.” The QuickType bar should then present you with the option to autofill “1234″ into the code field.

Note: iOS can recognize words equivalent to “code” or “passcode” in all supported iOS languages.

Tap Submit to display the Motivational view controller.

Password Ninja Enlightenment Attained!

Take a moment to get thoroughly inspired by your random motivational quote, then open Safari on your iOS device. Navigate to your login web page by replacing “[your domain]” with your actual domain in the following url:

https://[domain name]/login

Upon tapping the Username field, your web page should present you with the same credentials that you saved during sign up in your iOS app.

Likewise, if you create a new account via Safari at https://[domain name]/register and return to the iOS app to login, those credentials should autofill.

Where to Go From Here?

Whew! That was a lot of work, but you’ve achieved a lot for your efforts. You’ve now implemented iOS password autofill, generation and synchronization. The login action to your app is now secure, easy to use and integrated directly with your website!

If you haven’t already done so, download the tutorial materials using the Download Materials button at the bottom or top of this tutorial. Look through the final project to see how it compares to your version.