Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get iOS 12 Autofill to ask to save password in React Native app?

PROBLEM

I'm on React Native 0.59.9 (latest at the time of this post), and have a login screen in my mobile app that I would like iOS 12's autofill feature to pick up and save the password for a new user. With what I've set up, the app shows the keyboard with the autofill option but never pop's up the 'Save Password' for a new user's credentials.

What the keyboard autofill looks like right now: https://imgur.com/6gVpGbU

SOME BACKGROUND INFO

In React Native's documentation, they now expose textContentType in the TextInput component. To set it up for iOS 11 autofill, the username textContentType would be set to 'username' and the password textContentType would be set to 'password'.

RN textContentType documentation: https://facebook.github.io/react-native/docs/textinput#textcontenttype

For iOS 12 autofill, which is supposed to introduce the 'Save Password' feature to mobile app's as well now (previously was websites only) the configuration is different for the password.

The password textContentType would be set to 'newPassword' instead. This isn't working though, in fact it seems to be buggy and breaks the app as it suggests username's for the password field with this set...

Implementation

What I've tried to do to implement iOS 12's autofill feature in React Native:

<TextInput
  placeholder={'Enter username'}
  autoCapitalize={'none'}
  autoCorrect={false}
  textContentType={'username'}
/>
<TextInput
  placeholder={'Enter password'}
  autoCapitalize={'none'}
  autoCorrect={false}
  secureTextEntry={true}
  textContentType={'newPassword'}
/>

In the mobile provision, I've made sure to enable Associated Domains as an entitlement. (Done through Apple Developer website).

In my domain (for example www.mydomain.com), the file apple-app-site-association (with no extension) that has the following has been put into the root directory and is publicly available (https supported).

{
    "webcredentials": {
        "apps": [
            “ZT978FY6AB.com.company.my.app”,
        ]
    }
}

In XCode, I've set up the Associated Domains to point to that domain. Example:

webcredentials:www.mydomain.com

OUTPUT

The expected output of implementing this is that iOS pops up the 'Save Password' dialog when a new user enter's their credentials.

What the pop up dialog should look like: https://imgur.com/GH4hfP8

Instead, it never pops up. The user just heads straight into the app upon successful login without the dialog ever appearing for saving the password. This essentially means that none of my users can save their credentials to the password manager of their choice (not even iCloud keychain).

Since this feature does not seem to be testable on a simulator, I've been testing it on an iPhone 7 Plus with iOS 12.3.1 installed and autofill enabled in the settings as can be seen in the below image.

https://imgur.com/nSEmy7V

Any ideas what I'm doing wrong, or if I'm missing a step?

like image 443
Yusuf Ismail Avatar asked Jun 10 '19 10:06

Yusuf Ismail


People also ask

How do I get my iPhone app to auto fill Passwords?

Go to device Settings. Tap Passwords & Accounts > AutoFill Passwords. Turn on AutoFill Passwords.

Can iPhone AutoFill Passwords?

When you sign up for services on websites and in apps, you can let iPhone create strong passwords for many of your accounts. iPhone stores the passwords in iCloud Keychain and fills them in for you automatically, so you don't have to memorize them.


1 Answers

Got it working! The following was what I did to get it working.

Steps

  1. In the app, in code the username and password fields are as below (notice the textContentType)
<TextInput
 placeholder={'Enter username'}
 autoCapitalize={'none'}
 autoCorrect={false}
 textContentType={'username'}
/>
<TextInput
 placeholder={'Enter password'}
 autoCapitalize={'none'}
 autoCorrect={false}
 secureTextEntry={true}
 textContentType={'password'}
/>
  1. Enable Associated Domains as an entitlement in the mobile provision
  2. In XCode, set the Associated Domains to point to the site which will host the apple-app-site-association file.
webcredentials:www.example.com

Do not include the https part of the URL, and do not include the end which would be /apple-app-site-association

  1. Place the apple-app-site-association file in the root directory "/" of your website and make sure it's publicly available. You can check this in any browser by entering your websites full url with the ending like so:
https://www.example.com/apple-app-site-association 

You can try this out on the YouTube URL and Amazon URL as well to see their apple-app-site-association files as an example.

  1. Delete your previous builds from the phone and re-install the new builds with these changes and Apple should make the connection almost immediately. Your first successful new login with fresh credentials should then be prompted with the iOS 'Save Password' pop up. You're done!

Now my users can login with autofill, and the best part is that iOS offers to autofill using touch ID, face ID or passcode depending on the user's phone's setup. So they can login using touch ID or even face ID with no extra work needed in the RN app to get this working. Better yet, if they save it to iCloud, they can move to another device and still be able to login to the app with the same credentials if they want to.

The mistakes I made:

I made a few mistakes, hopefully you can avoid these by reading the following.

  1. The website that hosts the apple-app-site-association has to adhere to Apple's guidelines fully. I made the mistake of initially using a temporary site hosted on AWS. This AWS URL provided both a http and https. Apple did not like this. When I switched over to a website that only hosted https it worked fine. This is critical for the 'Save Password' to work, otherwise Apple doesn't have a key to save your credentials to (it uses your website domain as the key to save the credentials to in the Apple keychain).
  2. The apple-app-site-association syntax matters. If even one of the special symbols is off, it won't work. In my original file above take a close look at the double quotes encapsulating the app id:
{
    "webcredentials": {
        "apps": [
            “ZT978FY6AB.com.company.my.app”,
        ]
    }
}

They aren't the standard double quotes and this was resulting in a file that couldn't be parsed by Apple. When in doubt, copy the one that Apple provides in their documentation page and then modify it's contents as necessary. Changing it to the normal double quotes like below fixed that:

{
    "webcredentials": {
        "apps": [
            "ZT978FY6AB.com.company.my.app",
        ]
    }
}
  1. In the RN side of things all you need is the textContentType={'username'} and textContentType={'password'}. My mistake was thinking that 'newPassword' was needed to prompt the 'Save Password' dialog. Nope. 'newPassword' is used by autofill to suggest strong passwords to new users. In essence, only use 'newPassword' on forms where the user is doing a sign up. Not for login forms.

Something to clarify, this solution works for apps that are just apps. No website with a login required, no bringing over credentials from a website into the app needed, and no webview login setups necessary. This was not apparent when I was going through documentation about autofill. The website that hosts the apple-app-site-association does not need to have any login or anything of the kind, it can just be a plain website with a bit of information (possibly about the app or the company that makes the app).

like image 158
Yusuf Ismail Avatar answered Sep 19 '22 17:09

Yusuf Ismail