Automatically generated passwords in iOS 12

    If your application has a registration function that includes the ability or necessity to enter a new username and password, you will most likely be interested in the innovation in “iOS 12” , which I would like to describe. This is a service that comes up with new passwords for the user, automatically inserts them into the required fields and safely stores them in Keychain .

    Automatically generated system passwords are the most resistant to selection (being randomly generated sequences of characters - adjusted for customizable restrictions, but more on that later), relieve application users from having to invent a sequence on their own and flexibly adjust to the needs of a particular application. Support for new functionality is quite easily provided, but not without features. But first things first.

    Rights and obligations

    First of all, the application must declare its desire to use this functionality. In the “Capabilities” list of the corresponding “Target”, you must first have a domain in the “Associated Domains” list . Strangely enough, the application must have an “Associated Domain” in order to be able to use the generated passwords and store them in the user's Keychain (these two functions are interconnected, and generation cannot be used separately from storage).

    If the application already supports the use of shared accounts with your site (the so-called "Shared Credentials") , then this step is already behind. Also, it may already be behind, and if the application supports "Universal Links"or another mechanism for handling external "URL" links.

    Anyway, after adding this compatibility, the application will have a new “Entitlement” .

    In addition to this more general compatibility, the application should also have “Capatibility” “AutoFill Credential Provider” - this allows the application, if it has permission from the user, to use the system logins and passwords. Adding this compatibility will cause the “AutoFill Credential Provider Entitlement” permission to appear .
    By the way, adding this and other features is available only to members of the Apple Developer Program .
    The two functions listed must also be included in the Provisioning Profile application.

    Dependencies used

    Adding the appropriate compatibility will cause the “AuthenticationServices” framework to appear in the Linked Frameworks and Libraries list of the corresponding “target”. This moment has some features that are worth mentioning. Firstly, the automatic addition of the associated framework may not “work” the first time: when you run the application on a real device from my instance of Xcode version 10.1, the application immediately “crashed” due to the lack of “AuthenticationServices”. Manual removal of the framework and adding it back to the list of related components solved the problem.

    Secondly, the automatic addition of the framework marks it as “Required”. If your application implies the ability to work "under" "iOS" versions below 12, it will also cause it to crash at the launch stage "from under" operating systems of lower versions. "AuthenticationServices" are available only for version 12th systems. This problem is solved by marking the framework as “Optional” .

    Support in text fields

    To support the functionality of text fields, a textContentTypeprotocol variable is used UITextInputTraits. The class UITextFieldthat is most likely used to enter the login and password in the application already implements the requirements of the protocol we need.

    textContentTypeIs a field of type UITextContentTypecontaining only a set of constants. We need at the moment - newPasswordused to enter a new password that is currently being invented (not to be confused with just passwordused to enter an existing password).

    let passwordTextField = UITextField()
    if #available(iOS 12, *) {
        passwordTextField.textContentType = .newPassword

    Setting the value is textContentTypewrapped in the “API” availability check , because, like the general functionality, this constant is only available starting from “iOS 12”.

    In addition to the content type, the text field must ensure secure data entry:

    passwordTextField.isSecureTextEntry = true

    Although the application may well provide the functionality popular in our time to show and hide the entered password, the generated password will be offered only if at this moment the flag matters true.

    An interesting moment is connected with the content type of the text field: if there is no other field on the screen, with the content type username, the automatically-generated password will not be offered. This is due to the fact that the functionality is based not only on the specified content type of the text field, but on the heuristic analysis of the screen contents .

    It seems that the password generation “breaks” the logic of the screens that require you to enter a new password for verification twice. At least, I have not yet found a way to use these two functionalities together. And it looks likeI am not alone .

    It is worth mentioning that if the login semantically is an email address (and, therefore, really want to have the appropriate type of keyboard), the keyboard and content types can be combined:

    let userNameTextField = UITextField()
    userNameTextField.keyboardType = .emailAddress
    userNameTextField.textContentType = .username

    Password Requirements

    Often, user passwords must comply with certain rules (have a certain length, include certain characters, etc.). These rules can be specified so that the system takes them into account when generating passwords. This is done through the passwordRulesprotocol property UITextInputTraits. For example:

    if #available(iOS 12, *) {
        passwordTextField.passwordRules = UITextInputPasswordRules(descriptor: "required: upper; required: lower; required: digit; minlength: 8;")

    The property is also available only starting with "iOS 12".

    Property Type - UITextInputPasswordRules. Initialization - using the string-handle. The descriptor has an uncomplicated syntax and consists of simple password requirements, separated by a semicolon. Each requirement is a key-value pair, separated by a colon. A key is a type of a rule (for example, “necessarily includes” - required), and a value is an element that must follow this rule (for example, the digits - digit).

    In the example above, the descriptor means:

    • required: upper - the presence of at least one capital letter is required;
    • required: lower - the same for at least one lower case letter;
    • required: digit - the same for at least one lower case number;
    • minlength: 8 - The minimum length is eight characters.

    A detailed listing of possible keys and values ​​can be found in a nice article published on the NSHipster website .

    And “Apple” offers a rather convenient assistant for writing descriptors , which provides not only a convenient way of constructing them, but also checking the generated descriptors in the form of an unlimited number of generated examples. There you can see which rules are applied by default.


    Just in case, it should be clarified that the password generation mechanism does not provide validation of the data entered by the user - you need to take care of this yourself. Which, of course, is quite logical, since The user of the application can reject the proposed auto-generated password or even prohibit the generation of passwords and auto-complete fields.

    Interface builder

    What is remarkable and in the spirit of our time, all of the listed text field settings can be set in “Interface Builder” , up to “Password Rule”:


    Functionality check

    The functionality is not complicated, but it has a number of nuances: when setting it up, you can easily forget something. In this case, in the “debug” assemblies, when the corresponding text field is activated, the reason for which the functionality is not currently in effect will be displayed in the console.

    For example:

    [AutoFill] Cannot show Automatic Strong Passwords for app bundleID: <...> due to error: Cannot save passwords for this app. Make sure you have set up Associated Domains for your app and AutoFill Passwords is enabled in Settings

    You should also always keep in mind that this type of functionality is among the actions for which user permission is required. In this case, as many as two are required:

    1. iCloud Keychain;
    2. AutoFill.


    This seems to be all that should be addressed while providing support for the new functionality. If someone in the process of working on this has come up against other interesting features, I will once comment and, if necessary, be sure to supplement the article.

    The feature is quite interesting and, if used properly, is quite capable of improving the user experience of your application!

    Also popular now: