Skip to main content
This page covers the SNA-only integration of the OTPless Headless SDK on iOS. The SDK accepts the requestId generated by the Create API, performs the silent network handshake, and reports progress through callbacks. Your backend confirms the final result via the Status Check API.

Requirements

RequirementVersion
iOS13.0+
Xcode12.0+
Swift5.5+

Step 1: Add SDK dependency

The SDK can be installed via CocoaPods or Swift Package Manager. Find the latest version of the SDK here.
# Add to your Podfile's dependencies section
pod 'OtplessBM/Core', 'latest_version'
For CocoaPods, run the following in your root folder to fetch the dependency:
pod repo update
pod install

Step 2: Configure Info.plist for SNA

Add the following block to your Info.plist only if you are using the SNA feature.
  • If the NSAppTransportSecurity key is not already present, add the entire block below.
  • If the NSAppTransportSecurity key is already present, add the listed domains one by one under NSExceptionDomains.
Info.plist
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>api-csp.airtel.in</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>v4-api-csp.airtel.in</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>in-vil.ipification.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>partnerapi.jio.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>
Make sure Silent Network Authentication is enabled on the OTPLESS dashboard. For an SNA-only configuration, SNA must be the only channel enabled. Learn more about Silent Network Authentication.

Step 3: Start SNA with the requestId

Pass the requestId returned by the Create API to start():
otplessTask?.cancel() // Cancel any ongoing tasks to prevent request duplication

let request = OtplessRequest()
otplessRequest.set(fromBackend: "REQUEST_ID_FROM_API")

otplessTask = Task(priority: .userInitiated) {
    await Otpless.shared.start(withRequest: request)
}
Start polling the Status Check API from your backend immediately after calling start(). The SDK callback and the server status run in parallel.

Step 4: Handle callbacks

func onResponse(_ response: OtplessBM.OtplessResponse) {
    Otpless.shared.commitOtplessResponse(response)

    switch response.responseType {
    case .SDK_READY:
        // SDK initialized successfully — enable your continue button
        // or proceed with user authentication.
        print("SDK has been initialized successfully.")

    case .FAILED:
        // SDK initialization failed
        if response.statusCode == 5003 {
            print("SDK initialization failed, please try to initialize the SDK again")
        }

    case .INITIATE:
        // Authentication has been initiated
        if response.statusCode == 200 {
            let authType = response.response?["authType"] as? String
            if authType == "SILENT_AUTH" {
                // SNA is being attempted — show a loading state.
            }
        } else {
            handleInitiateError(response)
        }

    case .ONETAP:
        // Final success response with token / idToken
        if response.statusCode == 200 {
            if let data = response.response?["data"] as? [String: Any] {
                if let idToken = data["idToken"] as? String, !idToken.isEmpty {
                    // Process idToken and verify it on your backend.
                }
                if let token = data["token"] as? String, !token.isEmpty {
                    // Process token and verify it on your backend.
                }
            } else {
                print("Token not received")
            }
        } else {
            print("Token verification failed")
        }

    case .AUTH_TERMINATED:
        // SNA-only configuration: auth could not complete.
        // Emitted when pre-checks fail, or when SNA was attempted
        // and then failed/expired. Treat as a terminal failure and
        // rely on the Status Check API for the final outcome.
        break
    }
}

Callback reference

The SDK works in two steps — initialization and start() — and each step has its own set of callbacks.

Step 1: Initialization callbacks

Emitted when the SDK initializes.
CallbackMeaning
SDK_READYSDK initialization completed.
FAILEDSDK failed to initialize (e.g. statusCode 5003).

Step 2: Start callbacks

Emitted after you invoke start() to begin authentication.
CallbackStateMeaning
INITIATENon-terminalSNA is being attempted after pre-checks pass. authType is SILENT_AUTH.
ONETAPSuccess — terminalSNA completed successfully (Silent Mobile Verification). Returns token / idToken.
AUTH_TERMINATEDFailed — terminalEmitted in two cases: (1) pre-checks failed → terminated directly; (2) SNA was initiated and then failed/expired.
For the errorCode / statusCode values surfaced in SDK callbacks, see SDK Error Codes.

Next step

Status Check API

Confirm the authoritative auth status from your server.