react-native: Most TextInput textContentTypes don't work due to mismatched string constants

Environment

  React Native Environment Info:
    System:
      OS: macOS 10.14
      CPU: x64 Intel(R) Core(TM) i7-7567U CPU @ 3.50GHz
      Memory: 36.17 MB / 16.00 GB
      Shell: 5.3 - /bin/zsh
    Binaries:
      Node: 8.11.3 - /var/folders/5f/6g410wwx743d7_wx8lphvzfc0000gn/T/yarn--1544413987073-0.5166565719343945/node
      Yarn: 1.12.1 - /var/folders/5f/6g410wwx743d7_wx8lphvzfc0000gn/T/yarn--1544413987073-0.5166565719343945/yarn
      npm: 5.6.0 - ~/.n/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
      Android SDK:
        Build Tools: 23.0.1, 23.0.3, 25.0.0, 25.0.2, 25.0.3, 26.0.1, 26.0.2, 27.0.3
        API Levels: 23, 25, 26
    IDEs:
      Android Studio: 3.1 AI-173.4819257
      Xcode: 10.1/10B61 - /usr/bin/xcodebuild
    npmPackages:
      @storybook/react-native: ^4.0.2 => 4.0.6
      react: 16.6.1 => 16.6.1
      react-native: 0.57.7 => 0.57.7

Description

The strings used for textContentType are passed directly though to iOS, however they don’t match up with the underlying string constants used in iOS.

I ran the following code in a playground to source the underlying values of the TextContentType constants:

import UIKit
print(UITextContentType.URL.rawValue)
print(UITextContentType.addressCity.rawValue)
// etc...

Here are the values that I got.

React Native iOS
URL url
addressCity address-level2
addressCityAndState address-level1+2
addressState address-level1
countryName country-name
creditCardNumber cc-number
emailAddress email
familyName family-name
fullStreetAddress street-address
givenName given-name
jobTitle organization-title
location location
middleName additional-name
name name
namePrefix honorifix-prefix
nameSuffix honorifix-suffix
nickname nickname
organizationName organization
postalCode postal-code
streetAddressLine1 address-line1
streetAddressLine2 address-line2
sublocality address-level3
telephoneNumber tel
username username
password password
newPassword new-password
oneTimeCode one-time-code

According to this table the only textContentTypes that will work currently in React Native are: username, password, location, name and nickname.

Possible Solutions

The simplest solution would be to update textContentType to use the iOS strings instead of current keys.

Alternatively a mapping in the native code could allow us to keep the existing strings and just silently translate them.

My preferred solution is to map each string to the named Objective-C constants which I’ve created a PR for #22579.

Reproducible Demo

I’ve created a demo snack which allows you to try each textContentType with both the React Native and iOS strings: https://snack.expo.io/@levibuzolic/textcontenttype

Note: In my testing, most (if not all) textContentType values don’t work on the simulator, instead they need to be tested on a real device.

Example Screenshots

addressState address-level1
img_1579 img_1578
newPassword new-password
img_1582 img_1581

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 6
  • Comments: 27 (12 by maintainers)

Commits related to this issue

Most upvoted comments

Why is this issue closed? I do experience problems with this, especially trying to implement oneTimeCode autofill from text messages.

@albinhubsch because the first PR for it was merged, but then reverted. I can’t re-open the issue.

There’s a new PR up for it, been trying to get it in for a while. https://github.com/facebook/react-native/pull/22611

@makozlo-airship @levibuzolic Hey guys, seeing the same thing where the textContentType does not auto suggest on a real device. Here is the Snack I am testing with https://snack.expo.io/SkVvVhq94.

Oh sorry @t2, looks like latest Expo (v32) is only on React Native 0.57, my PR went out in 0.58.6.

I’ve built your snack locally on the latest version of React Native 0.59.5 and can confirm it’s working correctly:

IMG_2347

If you need to use Expo, you can work around this issue temporarily by using the iOS literal strings from the right column of the table I posted in my PR description, these will be passed through directly and should work for now (until Expo moves to React Native 0.58.6 or higher). You can see this working in this Expo Snack.

Make sure you leave a note for yourself to switch to the proper strings later!

  • must contain the words code, passcode or verification number
  • the number should appear after the above words
  • code must be numeric and between 3 and 8 digits without spaces
  • must not be using a custom keyboard

@levibuzolic I did not know requirements above. Thanks

@tsdmrfth by “not working” do you mean you’re not getting the keyboard accessory item? oneTimeCode has been working perfectly for us in a production app with tens of thousands of users.

I’d take a look at the format of your SMS as Apple has some specific requirements for oneTimeCode to work. I believe some of the requirements for the SMS are:

  • must contain the words code, passcode or verification number
  • the number should appear after the above words
  • code must be numeric and between 3 and 8 digits without spaces
  • must not be using a custom keyboard

Here’s a screenshot I took this morning of it in action on iOS 12.3.1 and React Native 0.59.10

IMG_2588

@makozlo-airship @levibuzolic Hey guys, seeing the same thing where the textContentType does not auto suggest on a real device. Here is the Snack I am testing with https://snack.expo.io/SkVvVhq94.

@makozlo-airship - @levibuzolic Is this available in the current release yet? I’m on RN 0.59.1 and I still can’t seem to get textContentType to work correctly.

Yeah it is, I’m reasonably sure its working in our project. Worth noting that most (maybe all) of the types don’t work correctly in the simulator and will only work on a real device. What issues are you having?

@timt not really, I’ve been trying to work out why the tests are failing but have t had much luck they seem unrelated to the PR.

I’ll get it up to date with master again and see if that sorts things out.