The Phone module collects a user's phone number and can confirm phone ownership by sending a one-time password (OTP) via SMS.
For an overview of this module and how it works, see Phone Number Input.
How you use this module depends on your integration pattern. When the app defines the steps in code, you add the module to an IncdOnboardingFlowConfiguration as shown below; when the flow is defined in Dashboard, you reference it by ID. See Integration Approaches.
Availability: All variants; the -sna build adds Silent Network Authentication features.
UI: v1 and v2.
Add Phone
Add the module with addPhone(). Every parameter is optional; call addPhone() with no arguments to use the default configuration.
flowConfig.addPhone(
otpVerification: true,
defaultRegionPrefix: 1 // optional dial code, 1…9999
)
Example
The example below builds a flow with the Phone module, enables OTP verification, starts onboarding, and listens for the result through onAddPhoneNumberCompleted(_:) on IncdOnboardingDelegate.
final class VerificationCoordinator: IncdOnboardingDelegate {
func startVerification(sessionToken: String) {
let flow = IncdOnboardingFlowConfiguration()
flow.addPhone(otpVerification: true)
let session = IncdOnboardingSessionConfiguration(token: sessionToken)
IncdOnboardingManager.shared.startOnboarding(
sessionConfig: session,
flowConfig: flow,
delegate: self
)
}
// MARK: - IncdOnboardingDelegate
func onAddPhoneNumberCompleted(_ result: PhoneNumberResult) {
// Phone number captured. Process the result.
let phone = result.phone
}
}
Configuration Options
Configure the module with addPhone().
| Option | Type | Description |
|---|---|---|
otpVerification |
Bool? |
If true, shows OTP verification after the user enters a phone number. When nil, shows the value configured in the Phone Number Input module in your Dashboard flow, or the manager flag. |
defaultRegionPrefix |
Int? |
Sets a dialing prefix that overrides the prefix derived from the carrier or the device's current region. Valid values are integers greater than 0, up to four digits; invalid values are ignored and the default region prefix is used. Do not add a leading +. |
You can also enable SMS OTP globally on the manager with enableSMSOTPVerification: a UserDefaults-backed flag, false by default. OTP expiration and prefill have no addPhone() parameter: they are set in the Phone Number Input module in your Dashboard flow.
Validation
On the v2 screen, the Continue button is enabled by default and stays enabled until an error is shown.
- Typing never introduces an error message. It only clears one that the new value has resolved.
- Leaving a field reports a malformed value, but stays quiet about an empty required field until the user has tried to submit at least once.
- Tapping Continue validates everything, empty required fields included. From then on, leaving a field also reports an empty one.
Enable Silent Network Authentication
Silent Network Authentication (SNA) is a phone number verification method that authenticates users through their mobile network using real-time carrier signals. You can enable SNA for the Phone module. SNA Dashboard configuration is currently only available in Flows, not Workflows.
- Use an iOS SDK variant that includes the
-snasuffix: for example,5.52.0-s-sna. - In a Flow in Dashboard, turn on Enable SNA verification in the Phone Number Input module.
- Start the onboarding flow using one of the following approaches:
startFloworstartOnboarding: SpecifyconfigurationIdinsideIncdOnboardingSessionConfiguration, and provide it assessionConfigtostartFloworstartOnboardingmethod.- Sections: Specify
configurationIdinsideIncdOnboardingSessionConfiguration, and provide it assessionConfigtosetupOnboardingSession. Then callstartOnboardingSectionwith the Phone module provided toIncdOnboardingSessionConfiguration.
What the User Sees
With SNA enabled, the module verifies silently before asking for anything. The screen opens on Checking your device... while the network checks the number already on the session. Requires UX v2; on v1, SNA runs only after the user enters a number.
- Verified: The module ends on Phone number verified! and the input screen never appears.
- No number on the session: The input screen appears, and Continue retries SNA with what the user entered.
- Any other failure: With OTP on, the input screen appears and Continue sends an OTP instead. With OTP off, the module ends on Something went wrong and the flow moves to the next step.
The check never waits indefinitely. If the network does not answer in time, the input screen appears without SNA when OTP is enabled; when OTP is disabled, the module ends on Something went wrong.
Result
On UX v2, the module ends on a result screen, Phone number verified! or Something went wrong, and waits for the user to tap Continue before the flow advances. Both completions use it, whether the number was verified silently or through OTP. A failed OTP keeps the user on the code screen with a message they can retry from, so it does not end the module. Your delegate callback runs when the user taps Continue, not when verification finishes.
Phone delivers a PhoneNumberResult to the onAddPhoneNumberCompleted(_:) callback on your IncdOnboardingDelegate:
func onAddPhoneNumberCompleted(_ result: PhoneNumberResult)
PhoneNumberResult fields:
phone: String?: The phone number captured from the user;nilwhen unavailable.error: IncdError?: The error that occurred while capturing the phone number, if any; otherwise,nil.