Best Practices for OTP Input Forms in iOS
Time to read:
Best Practices for OTP Input Forms in iOS
One-time passwords (OTPs) have become a go-to solution for secure user verification, bridging the gap between security and user experience. Whether delivered through SMS or email, OTPs provide a reliable way to confirm user identity and enable frictionless authentication.
The appeal of OTP verification lies in its simplicity—users don't need to remember complex passwords or download additional apps. For iOS developers, creating an effective OTP experience requires attention to several key implementation details that can make or break the user experience.
In this guide, we'll explore how to build a seamless, secure OTP verification flow for iOS apps.
Need OTP for other platforms? Check out our companion web HTML version.
OTP workflows and use cases
The basic flow for OTP verification looks like this:
- The user enters their phone number or email and submits the form to the app.
- The app generates a token (for example:
123456
) and sends the token to the user’s phone number or email. - The user enters the token into the OTP verification form.
- The app verifies the token.
This simple workflow has become nearly ubiquitous. The use cases for OTP verification include:
- Contact information verification: Whether it is with email, SMS, voice, or WhatsApp, OTP can be used to authenticate the user’s identity via their contact information.
- Two-factor authentication: OTP can also be used as a second authentication factor in combination with another—such as username and password—proving that the person logging in is the person who owns the account.
- Account recovery: OTP verification is a common method to provide users a way to restore access in case of lost passwords or other account recovery situations.
OTP has several advantages over other authentication methods. For example:
- OTP verification is passwordless and does not require the user to remember yet another password.
- OTP verification does not require a separate app, reducing friction.
- When implemented well, OTP verification has a streamlined UX, as the OTP token will be auto-filled and submitted for the user. They do not need to exit the current app.
However, even with these advantages, keep in mind that no mechanism is perfectly secure. The security of OTP verification depends on the security of the underlying phone number or email account. Additionally, phishing and recycled phone numbers can present issues.
Let’s look at how we can streamline the process and secure it.
Best Practices for OTP Verification on iOS
To streamline and secure the OTP Verification process, follow these best practices:
- Decide on the design of the input field
- Create a proper input field.
- Send the user a domain-bound OTP to enable autofill.
Decide on the design of the input field
For the input field of the OTP, you can either use a single input field or multiple input fields (one for each digit). If you’re having trouble choosing, the most common approach is opting for the multiple input field solution. This selection makes it clear to users how many digits they must input, and it uses all of the available screen space. It also provides a way to highlight to the user which digit they are currently entering.
However, multiple input fields add complexity regarding handling cursor movement between fields. Additionally, you must also handle autofill or pasting the OTP code into the fields. These problems are solvable, but do require some extra effort. We cover some solutions to these problems later in the article with a few troubleshooting tips.
Using a single input field is generally simpler, as it simplifies the implementation of autofilling and/or pasting. A single input field does not need any additional logic to handle cursor management.
A hybrid solution is also possible, where a single input field is styled as multiple inputs. Visually, the user will see multiple inputs, but on the backend, your app treats this as a single input. With an awareness of the tradeoffs involved, any of the above approaches can yield an effective OTP input field that provides a smooth user experience.
We'll show examples of how to build this with SwiftUI.
Create the OTP input field using a single input field
Here is an example of a single input OTP field using SwiftUI.
Note the following key takeaways from this example:
keyboardType
is set tonumberPad
. This tells the system to use the numeric keypad for entering the OTP.textContentType
is set tooneTimeCode
. This tells the system to use AutoFill for the field when a domain-bound SMS code is received. For more on this, see the Apple Developer documentation.
A single input field makes accessibility and keyboard management simple. The interaction is direct—you tap where you type. Native text selection and cursor behavior are maintained, along with built-in iOS text editing gestures.
Create the OTP input field for multiple digits
In the case of implementing a multiple digit design, you would use a hidden text field with a visual representation on top. Here is an example using ZStack
in SwiftUI:
Here are some key things to keep in mind from the above example:
- We create a
ZStack
containing a hidden text field as well as a visual representation. - On the hidden text field, we have set the
keyboardType
tonumberPad
and thetextContentType
tooneTimeCode
as before. This ensures compatibility with the iOS numeric keypad and with AutoFill, as in the single input version. - The visual representation dynamically adjusts to the number of digits needed.
- We maintain a single source of truth through the
otpText
variable, avoiding potential sync issues.
With this implementation method, we still get the AutoFill of the single input version, but build our own visual layer on top. This gives us the freedom to freely customize the appearance according to brand guidelines or other design requirements.
Handling form submission and autofill completion
Once users complete entering their OTP—whether through autofill or manual input—you need to handle form submission gracefully. The key is detecting when the code is complete and deciding whether to auto-submit or wait for user action.
For automatic submission when the OTP is complete:
This approach works particularly well with autofill, creating a seamless experience where the code appears and submits instantly. However, consider adding a brief delay (200-300ms) before auto-submission to give users a moment to see the completed code—especially for manual entry, where users might want to double-check their input.
For cases where you prefer manual submission, provide a submit button that becomes enabled when the code is complete.
Send the user a domain-bound OTP
To enable AutoFill in iOS, we need to send a domain-bound OTP. By providing the OTP in a specific format along with the domain, we instruct mobile systems to autofill that OTP only to our authorized domain. This increases the friction required for entering an OTP, which helps to prevent it from being entered on a fake domain.
First, you must associate the correct domain with your application. Add the Associated Domains Entitlement to your app, then add your domain to the entitlement.
Next, you must send the SMS in the proper format. The last line of the SMS must contain the @
symbol, your domain name, the #
symbol, and then the one-time code. Here is an example of a properly formatted SMS:
You can set up domain-bound OTPs via Twilio Verify through the use of a custom template.
When used with an appropriately configured input field, this enables AutoFill—increasing ease of use, lowering friction, and decreasing the likelihood of phishing attacks on your OTP input.
Testing and Tips
After configuring your input field and SMS delivery, the following guidance will help you test your implementation.
Troubleshooting cursor management or AutoFill issues
If you are using multiple input fields, ensure that the user knows which digit they're currently entering. Because there are multiple fields, built-in cursor management doesn't apply. So, it is essential to provide that information to the user separately, using visual indicators such as border highlighting, contrasted background colors, or even a blinking cursor or line in the active field.
If you're having trouble with AutoFill, make sure that you have met the requirements:
- Associated the domain with the app
- Correctly formatted the last line of the SMS
- For your input field, set the
textContentType
tooneTimeCode
Testing and rate limiting
Keep in mind when testing that you are receiving real SMS and will be subject to the protective rate limits of the Verify API. Twilio Verify provides workarounds for testing, including completing or canceling the verification by calling specific endpoints.
Handling errors
Don’t forget to handle error cases. Your form should allow the user to resend and retry the OTP, but with a timeout to prevent bad actors. You can also provide alternative channels, such as voice calls, after the user has attempted to authenticate using other methods first.
Conclusion
Building an effective OTP verification system for iOS creates a user experience that feels both secure and effortless. When you combine intuitive input field design with iOS's built-in AutoFill capabilities, you're not just authenticating users; you're building trust and reducing friction in your app's most critical moments.
The implementation details we've covered—from choosing the right input approach to formatting domain-bound SMS messages—work together to create a verification flow that users barely notice, which is precisely what you want. When OTP verification works seamlessly, users can focus on what they came to your app to do.
Additional Resources
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.