[ Music ]
Hello, and welcome to the session on implementing AutoFill Credential Provider Extensions.
In this video, I'll first give an overview of the Password AutoFill feature and how it is improved in iOS 12.
After that I'll go into detail about how Password Manager apps can now integrate with Password AutoFill using new APIs in iOS 12.
And along the way, I will recommend a few best practices to take as you adopt these new APIs.
First, let's talk about Password AutoFill.
iOS 11 brought two major improvements to Password AutoFill.
First, the most relevant credentials were displayed directly on the QuickType bar, so they're only one tap away, and second, iOS 11 brought password AutoFill to apps.
This makes it super convenient to use credentials from iCloud keychain, whether they're needed on the web or in apps, like the shiny app you just saw.
And new in iOS and tvOS 12, you can also use password AutoFill in Apple TV apps by selecting credentials to fill from an iOS device.
These features are great for users of iCloud keychain, but some users rely on other password manager apps to store their credentials.
To make it just as convenient for these users to access their safe credentials, iOS 12 allows password manager apps to participate in AutoFill for the same experience as iCloud Keychain.
In iOS 12, there is a new UI for password AutoFill settings, which allows users to select an app to provide credentials to AutoFill, in addition to or instead of iCloud Keychain.
Using the QuickType bar, the user can bring up a list of their credentials saved in the password manager.
This UI is provided by an extension bundled with the password manager app.
When a credential is selected, the extension hands it back to AutoFill, and the username and password are filled in the app.
Of course, this also works with the QuickType bar suggestions as well.
AutoFill can now surface the best credentials as defined by the app, so they're accessible with just one tap.
When using these credentials, the app extension can optionally show its own UI to authenticate the user before filling the credential.
This integration makes logging into apps even easier for users of password manager apps, as they no longer need to switch apps to copy their credentials.
It also makes Password AutoFill available in more apps.
Any app that supports AutoFill from iCloud Keychain will now work with Password Manager apps, without any additional work.
With that overview, let's dive into how you can implement these capabilities in your password manager app.
There are four main steps I'll cover.
First, you'll need to configure your project to take advantage of some new APIs.
This involves adding a capability to your app and an extension to your project.
AutoFill will use this extension when it needs to consult your app or show its UI across the system.
Next, your extension will need to support showing the user a list of their credentials to choose from when they open your extension from the QuickType bar.
After that, if you want AutoFill to show your app's credentials in the QuickType bar, you will need to add support for this by telling the system about the credentials you want to show, and implementing another API in your extension to respond to users selecting those credentials.
And finally, you may want to take advantage of an API that will allow you to present your extension's UI when users enable your Password Manager in Settings.
Let's talk about these steps in more detail.
First, you will need to make a few changes to your project.
This starts with enabling AutoFill Credential Provider in your app's capabilities.
This adds a required entitlement to your app, and links it to the new authentication services framework, which provides the APIs for Password Autofill integration.
Next, you will need to add an AutoFill Credential Provider Extension target to your project.
Xcode 10 includes a new template for this extension.
The template will create a view controller class for you.
A subclass of AS credential provider view controller.
When AutoFill needs to invoke your extension, it will create an instance of this class and call certain methods on it, which your subclass will override.
So once you've configured your project, the first thing to implement in your extension is the list of credentials that the user can bring up from the QuickType bar.
Here is how this works.
When the user is signing into an app, they can use the QuickType bar to bring up your credential list.
At this point, AutoFill will launch your app extension and let it know where the user is logging in, so you can suggest the most relevant credentials.
AutoFill will do this by preparing a list of AS credentials service identifier objects, representing the service the user is currently using.
Your extension may receive multiple service identifiers, if AutoFill can determine multiple better [inaudible] to use in the current context.
In apps, service identifiers are based on the app's associated domains.
Apps that have adopted universal links hand-off or shared web credentials will have associated domains.
For example, the Shiny app is associated with shiny.example.com, so AutoFill will provide your extension a service identifier of type domain for shiny.example.com.
In Safari, the service identifiers are based on the URL of the current page the user is logging into.
AutoFill will send the service identifiers to your extension by calling the prepared credential list for service identifiers method on your view controller.
Here, your extension should set up its UI for displaying the user's credentials, and it can use the provided service identifiers to prioritize the most relevant ones.
From here, two things can happen.
If the user chooses to dismiss your extension, you tell the system about this by calling Cancel Request With Error on your view controller's extension context, and AutoFill will dismiss your extension.
Otherwise, if the user selects a credential they want to use, your extension creates an AS password credential object based on the user's selection and then hands it to AutoFill by calling the complete request with selected credential method on the extension context.
And AutoFill will use that credential to fill the username and password in the app.
There are a few best practices the credential list should adhere to for the best user experience.
First of all, be sure to include a button in your UI to cancel the request.
The user may change their mind about signing into the service, or realize they don't have a credential saved, so you should support letting the user dismiss your extension without selecting a credential.
Also, your credential list UI should make it possible to see all credentials, whether or not they match the service identifiers.
In some cases, the user may need to choose a credential from a different domain.
Allowing the user to access their entire set of credentials from the list, ensures your extension is always useful.
And user authentication is completely up to your extension.
If you need to authenticate the user, you should do so when the credential list is presented.
And that is how you can implement a credential list in your extension so your app's credentials are available to use when signing in anywhere.
Now we will make this even more convenient by allowing AutoFill to surface these credentials directly on the QuickType bar.
I'll start with an overview of how this process works, describing the roles played by your code, the system, and the app where the user is signing in.
To start with, your app needs to let AutoFill know ahead of time what credentials it wants to make available for the QuickType bar.
Your app provides AutoFill a list of credential identities.
The credential identity includes information about a credential, such as the username and the service, but not the password.
When the user begins signing into an app, the app talks to AutoFill, and lets it know when a username or password field is focused.
AutoFill then looks for appropriate credential identities to suggest for the app.
It does this by searching through the credential identities that your app has already provided, so your extension doesn't need to be launched yet.
If there are any matching credential identities to suggest, AutoFill displays them on the QuickType bar.
These suggestions are rendered privately by the system, so the app isn't yet able to determine what credentials the user has saved for the app.
When the user selects one of the suggestions, AutoFill launches your app extension to ask it for the full credential, including the password.
It will tell your extension which credential identity the user chose, then your extension looks up the password belonging to the selected credential in your app's password database.
At this point, the extension has the option to present its own UI before returning the password.
This is useful for password manager apps that ask the user to enter a master password, or perform another type of authentication specific to the app.
Once your extension has the password, it packages it in an AS password credential and hands it to AutoFill by completing the extension request.
If the extension didn't show its own UI, AutoFill will perform appropriate authentication for the user.
Depending on the device and the user's preference, this may be Face ID, Touch ID, Device Passcode, or None.
If that authentication is successful, AutoFill will fill the username and the password in the app.
There is a lot going on here, so I'm going to walk through the steps you need to take as a developer to support this workflow.
The three things you need to do are provide AutoFill with the credential identities you want it to suggest to the user.
Implement support in your extension to provide the passwords when those suggestions are selected, and display custom UI in your extension to authenticate the user before returning the credential, if your UX requires it.
Once again, this step is optional.
If you don't show custom UI for authentication, AutoFill will perform appropriate authentication for you.
Credential identities are represented by instances of AS Password Credential Identity.
This class contains all the information about a credential that AutoFill needs to know in order to determine where to offer it.
This includes a service identifier, which tells AutoFill which apps or websites to suggest the credential on.
The username of the credential, and optional record identifier string that you can use to correlate this identity to a record in your app's own database, and a rank parameter.
If the user has more credentials for a particular service than the QuickType bar can show, you can use the rank parameter to mark certain credential identities as higher or lower priority.
Credential identities having a higher rank value will be ordered before credential identities with lower ranks.
These credential identities get saved to the Credential Identity Store, which is the database inside your app's container that you can modify using the AS Credential Identity Store class.
AutoFill suggests credentials to the user by searching through your app's Credential Identity Store.
The Credential Identity Store is secured with complete unless open data protection, so no operations can start while the device is locked.
The system never syncs the Credential Identity Store to the Cloud or includes it in backups, so this information never leaves the device.
Each app has its own Credential Identity Store, and only the app and its extensions can modify it.
The store is only read by AutoFill for determining which credentials to suggest to users.
And the Credential Identity Store can only be modified while your app's extension has been enabled by the user.
If your extension is disabled, attempts to update the store will fail.
And if the user disables your extension or deletes your app, the Credential Identity Store will be deleted.
Your app should update its Credential Identity Store when it has new information about what credentials it can offer.
As an example, let's say your app uses an online service to store the user's credentials.
When the user signs in, your app would start retrieving the user's credentials.
At this time, you would update the list of credential identities in the store, so the newly-fetched credentials could be suggested on the QuickType bar.
As the user adds, removes, or modifies their credentials, your app updates the Credential Identity Store so it continues to accurately reflect this set of credentials that your app can provide.
These updates might be because the user locally makes changes within your app, or perhaps because your app is synchronizing changes from other devices signed into the online service.
Then, if the user were to sign out of the online service on the current device, your app would remove all the credential identities from the store, so the user doesn't continue to see suggestions for these credentials.
In your code, you use the AS Credential Identity Store Class to interact with the Credential Identity Store.
Using the Replace Credential Identities With and Remove All Credential Identities methods, you can replace or clear the list of credential identities that AutoFill will consider suggesting.
When individual changes are made, these saved credential identities or removed credential identities methods allow you to add, update or remove credential identities without completely replacing the contents of the store.
One important aspect of the system to understand is that the Credential Identity Store may be deleted at times that your app won't be able to predict.
As a few examples, if the user disables your extension for AutoFill, then later re-enables it, the system will have cleared the store.
If the system determines that your app provides credential identities, but consistently fails to provide the passwords when the user selects these credentials, the credential identity store may be deleted to prevent the user from seeing these stale credential suggestions.
If the user restores their device from a backup where they were using your credential provider extension, the store won't contain any credential identities since it wasn't included in the backup.
Your app should be able to handle these cases, and AS Credential Identity Store can help you detect these cases, so you can take the appropriate action when you need to update the store.
You can use the Get State method to ask the system about the state of your app's Credential Identity Store, return it as an AS Credential Identity Store State Object.
The first thing it tells you is whether or not the user has your app extension enabled.
You should check this before attempting to update the credential identity store.
If your extension is disabled, there is no point in trying to save or remove credential identities.
The State also has a Supports Incremental Updates Property, which you can use to determine if the Identity Store is intact since the last time you've updated it.
If you previously saved any credential identities to the store, this will return true, indicating you should use the incremental Save Credential Identities and Remove Credential Identities methods.
Otherwise, if the Store hasn't been written to yet, perhaps because your app was just disabled and re-enabled, Supports Incremental Updates will return false.
And you should populate the Identity Store by providing the full list of credential identities using the Replace Credential Identities With method.
Once your app starts saving credential identities to the store, AutoFill can start suggesting your app's credentials in the QuickType bar.
Next, you'll need to add support in your extension to provide the password when one of these credential suggestions is selected.
When this happens, AutoFill will first launch your extension and ask it for the password without presenting your UI on screen.
When it does this, AutoFill will call the Provide Credential Without User Interaction For method on your view controller, providing an AS Password Credential Identity, representing the credential being filled.
In this method, you will look up the associated password belonging to the given credential and hand it back to AutoFill using the Complete Request With Selected Credential method.
If your extension wants to have its UI presented at this point, cancel the extension request with the User Interaction Required error code in the domain AS Extension Error Domain.
The system will then call the Prepare Interface To Provide Credential For method on your view controller, and present its UI.
In this method, your extension sets up its UI for its workflow to provide the password.
When the password is eventually available, you return the credential to AutoFill, also using the Complete Request With Selected Credential method.
Once again, if your Extensions UI was presented, AutoFill won't perform any authentication before filling the returned credential.
It is up to your extension to decide what type of authentication is needed.
The most important thing to keep in mind when implementing this functionality is that your extension needs to respond to the initial non-UI request quickly, regardless of the results.
Your UI hasn't been presented yet, so it's not obvious to the user that your extension is working in the background.
If it takes a long time to return the password, the user may perceive the system, your app, or the service they're using as being unresponsive.
This would be a poor user experience.
And this is so important.
If a few seconds pass, and your extension hasn't returned the password, requested to show its UI, or canceled with another error, AutoFill will cancel the extension without filling the credential.
However, this timeout doesn't happen for debug builds, or when running on the simulator, so you can take your time to debug the extension without the system interrupting.
When you're implementing support for displaying your app's credentials on the QuickType bar, it's essential that you keep the Credential Identity Store up to date, and in sync with the credentials your app knows about.
If the store becomes out of sync with your app's data, the user might not see newly added credentials on the QuickType bar, or may continue to see credentials on the QuickType bar even after they've been deleted from your app.
You should take advantage of AS Credential Identity Store's incremental update APIs.
Replacing the entire list of credential identities every time any credential has changed, may become expensive the more credential identities you need to update.
It's better for performance to incrementally save new credential identities or remove deleted ones as those changes are made, rather than re-writing the entire store.
Keep in mind, when your extension is being called, the user is in the middle of using another app.
Keep the interactions and your UI to a minimum, and only include what the user needs in order to user their passwords.
If loading your password database involves expensive setup, avoid redoing the setup in the view load method of your view controller, and tearing it down later.
The system may reuse your app extensions process if the user sequentially signs into multiple services using your extension.
Consider using a singleton pattern, so any work done in one invocation of your extension can be reused the next time if it doesn't need to be repeated.
And that wraps up how you can display credentials from your app in the QuickType bar.
Finally, I'll discuss one more API your extension may find useful.
When the user enables your app extension for Password AutoFill, you may have some setup that needs to be done before the user can get the best experience.
For starters, if you support showing credentials in the QuickType bar, your app or extension will need to provide its credential identities to AutoFill first.
But it may also be useful to show other settings at this point, perhaps to offer the user the ability to sign in to an online service to retrieve the passwords if they haven't already.
Authentication services provides an API to support these work flows.
When these are enabled to your extension, settings can launch your extension and present its UI, so you can let users configure it.
To opt into this behavior, open the Info Property List for your app extension and add a new key under NS extension attributes.
AS Credential Provider Extension shows configuration UI with the bullion value of yes.
This is how the system will know to launch your extension when its enabled.
Then, implement the Prepare Interface For Extension Configuration method in your view controller, and set up the appropriate UI for when your extension is first enabled.
When your extension is done, call the Complete Extension Configuration Request method on your extension context, and settings will dismiss your UI.
At this point, your extension is enabled.
It has provided credential identities for AutoFill to suggest for the QuickType bar.
It can provide the passwords when those suggestions are chosen, and it can show the user a list of all their credentials.
You're now done integrating your app with Password AutoFill and the users can enjoy the convenience of AutoFilling Passwords saved into your app wherever they're needed.
There are just a few more general best practices to consider while developing your extension.
As discussed before, your principal view controller may be responsible for showing the UI for a diverse set of functionalities.
To achieve this, we recommend using separate view controllers managed by your principal view controller.
For example, you may want to have one view controller class for displaying the credential list.
And another for authenticating the user when filling credentials.
You can either present these view controllers from your principal view controller, or use view controller containment to embed their views.
And if you prepare your interface by presenting view controllers, the presentation should be done without animation, since the presentation of your principal view controller is already animated.
In general, extensions should be lightweight and ready to terminate when they're done, and this includes AutoFill Credential Provider Extensions.
Your extension will be invoked to perform one particular task, and you shouldn't include any unnecessary work flows or user interactions beyond what is needed.
Be aware that the system may terminate or suspend your extension for various reasons at any time.
For example, the system will terminate AutoFill Credential Provider Extensions while they're in use if the user switches apps.
And your extension will have a separate sign box from your main app, but it will still need to share data, such as the user's credentials.
Use App Groups or Shared Keychains to share data between your app and its extensions.
For a review about extension development in general, refer to the Creating Extensions for iOS and OS X part two session from WWDC 2014.
Finally, you can use Safari if you need to debug your credential provider extension while testing filling credentials.
To do this, first activate the extension scheme, select a target, and select Run.
When you do this, Xcode will ask you to choose an app to host the extension.
Choose Safari from the list, and click the Run button.
Safari will then open, and you can navigate to a sign-in page where you want to test your extension.
When you open your credential list, or select a credential from the QuickType bar, your extension will be launched, and Xcode will attach the debugger to it, so you can begin your debug session.
For debugging your extension in the other cases, use the Attach to Process Item in Xcode's debug menu to start attaching the debugger.
You can then manually open Settings to enable your extension if you want to test the settings UI, or you can open any app's login screen if you'd like to debug AutoFill there.
In summary, iOS 12 enables Password Manager apps to integrate with Password AutoFill.
Using APIs from the New Authentication Services framework, your credential provider extension can show the user a list of their credentials.
Show credentials on the QuickType bar, and optionally provide a way for the user to configure the extension from settings.
For more information, refer to the Apple Developer Page for this session.
To learn more about the other improvements to password management in iOS 12, see the Automatic Strong Passwords and Security Code AutoFill session.
And if you'd like to learn more about the Password AutoFill feature and associated domains, see the Introducing Password AutoFill for Apps session from WWDC 2017.