Passwords and Security Codes (OTP) are a modern necessity required for security and privacy. iOS 12 eases the tedious aspects of account setup and sign-in by automatically suggesting and using strong, unique passwords and by bringing one-time password to the QuickType bar so users can fill them with one tap. Here we'll learn how to implement these feature in your app.

First of all, we need to understand how it's work in iOS. So, When your app installs on an iOS device, the system attempts to associate the app with all the domains listed in the app’s associated domains entitlement:

  • The system takes each domain from the associated domains entitlement.
  • It tries to download the Apple App Site Association file (apple-app-site-association) for that domain.
  • If all the steps succeed, the system associates the app with that domain and enables Password AutoFill for that domain’s credentials.

So, first of all, we need to set up App Associated Domains.

1. Setup App's Associated Domains

To set up the Associated Domains in your app, open the projects Capabilities tab and enable Associated Domains. This step adds the associated domains entitlement to your app as well as the associated domains feature to your app ID. Now, To add your domain to the entitlement, click Add (+) at the bottom of the Domains table in order to add a placeholder domain with the webcredentials: prefix. To match all sub-domains of an associated domain, specify a wildcard with the prefix * before the beginning of a specific domain like *.developerinsider.co. Each domain you specify uses the following format:

<service>:<fully qualified domain>[:port number]

2. Add the Apple App Site Association File to your Website

Now, create a file named apple-app-site-association (without an extension). The apple-app-site-association file needs to be accessible via HTTPS with a valid certificate, without any redirects, at https://{domain}/apple-app-site-association. (like - https://developerinsider.github.io/apple-app-site-association)

{
    "webcredentials": {
        "apps": [
            "4F7SW76LL6.com.di.AutoPassword-iOS12",
            "4F7SW76LL6.com.di.AutoPassword-iOS12.QA",
            "4F7SW76LL6.com.di.AutoPassword-iOS12.Dev"
        ]
    }
}

Note
If your site uses different subdomains (such as developerinsider.co, developerinsider.in, and tech.developerinsider.co) each requires its own entry in the Associated Domains, and each must serve its own apple-app-site-association file.

To validate your apple-app-site-association file you can use Branch.io Apple App Site Association Validator or Apple App Search API Validation Tool.

3. Password AutoFill

Password AutoFill simplifies login and account creation tasks for iOS apps. By default, Password AutoFill saves the user's login credentials on their current iOS device. iOS can sync these credentials securely across the user’s devices using iCloud Keychain. Password AutoFill recommends credentials only for your app's associated domain, and the user must authenticate using Face ID or Touch ID before accessing these credentials.

To enable password autofill on a UITextField we need to set the textContentType property. Here the examples -

3.1 Login

Here the example defines text fields for logging in -

//username or email field
usernameTextField.textContentType = .username
usernameTextField.keyboardType = .emailAddress

//password field
passwordTextField.textContentType = .password

3.2 Signup

When creating a new account, we need to use the .newPassword text content type -

//username or email field
usernameTextField.textContentType = .username
usernameTextField.keyboardType = .emailAddress

//password field
usernameTextField.textContentType = .newPassword

3.3 Change Password

Also, when changing the password, username and new password text fields should be on the same screen, where username field can be read-only -

//username field
usernameTextField.isEnabled = false
usernameTextField.textContentType = .username
usernameTextField.keyboardType = .emailAddress
usernameTextField.text = UserDefaults.standard.username //logged in user username

//new password field
newPasswordTextField.textContentType = .newPassword
confirmNewPasswordTextField.textContentType = .newPassword

iOS supports Password AutoFill on UITextField, UITextView, and any custom view that adopts the UITextInput protocol.

4. Password Saving

iOS will automatically present an alert to save password if everything setup correctly. Here the compatibility checklist -

  • Tag fields with correct content types
  • Remove login fields from the view hierarchy
  • Clear login fields only after removing from the hierarchy
  • Check that AutoFill saved to the correct domain

5. Automatic Strong Passwords

If UITextField tag with .newPassword content type then system suggests a strong, unique password in apps that have an associated domain. It also saves any new credentials for that domain. Remember, username, password and new password text fields should be on the same screen. Here how autofills work

  • Check eligibility based on associated domains
  • Detect relevant sign up/change password form elements
  • Suggest a user name or user need to manually input username
  • Insert a strong password or user can choose their own password
  • Save the password after the user signs up or change the password

6. Custom Rules for Automatic Strong Passwords

Safari AutoFill has been able to generate automatic passwords since iOS 8, but it couldn't guarantee that a generated password satisfied the requirements of a particular service. In iOS 12, if your service has specific password rules, you can define valid password formats by setting the UITextField passwordRules property. This property takes a UITextInputPasswordRules object, which contains a rules descriptor string.

Here the example -

let passwordRuleDescription = "required: lower; required: upper; required: digit; minlength: 8; maxlength: 16;"
let passwordRules = UITextInputPasswordRules(descriptor: passwordRuleDescription)
passwordTextField.passwordRules = passwordRules

Note
The passwordRules property is supported only on UITextField objects, and the text field's secureTextEntry property must be set to true. The API is ignored if it is adopted on any other views.

You can use the Apple Password Rules Validation Tool to create custom rules if necessary. You can also generate and download example passwords from Password Rules Validation Tools to validate that your rules accurately reflect what your service accepts.

If the thought of working with a string-based format without a proper abstraction is not good. You can use PasswordRules, a Swift library for defining strong password generator rules.

7. Security Code AutoFill

If the system can parse a security code from an SMS message, the QuickType bar shows the code for up to three minutes after it has been received. If a security code arrives while the text input view is selected, the system pushes the incoming code to the QuickType bar.

To enable security code autofill on a UITextField we need to set the textContentType property to .oneTimeCode. Here the example -

otpTextField.textContentType = .oneTimeCode

To test the format of your SMS code for different languages, text a message to yourself. If you receive a message with an underlined security code, tap on the code. If a Copy Code option appears, the system has recognized your code.

8. A Note on when User Taps on an AutoFill Item

When a user selects an item from the QuickType bar, the system may ask them to authenticate using Face ID or Touch ID. Your app becomes inactive when Face ID or Touch ID appears that will trigger your app delegate's applicationWillResignActive: and applicationDidBecomeActive: methods. So, Don’t remove your user interface when these methods are called. If you do, the iOS won't be able to autofill the input fields. If you want to hide sensitive information when an app becomes inactive then you can make a check if the user is logged in or not.

9. Sample Project

You can download the sample project from GitHub.

References