iOS Authentication

Overview

Integrator must implement a token provider by adhering to TokenProvider protocol. The protocol consists of a single function - provideTokenReplacement which will be called by Sensibill SDK any time it requires a new or updated token.

Parameters:

  • A userIdentifier - this is the user identifier for which SDK would like to get a token refresh. It’s recommended to ensure that the provided user identifier is for currently authenticated user.

  • A completion callback, which will either return a Credentials object with valid access token, or an error.

Please ensure that provideTokenReplacement calls completion in all cases, either with Credentials or Error.

Steps

  1. (Recommended) Ensure the requested token is for currently authenticated user. The “current user identifier” can be stored wherever it makes sense for your app (for example in the class responsible for app authentication).

  2. (Required) Obtain a new access token from your integration server.

  3. (Required) Process the response from your authentication server. Although the exact operations you need to perform depend on your integration server implementation, the typical set of actions includes:

    • Check for errors. If error is returned, pass this error in callback to SDK
    • Parse the response to ensure the access token was obtained
    • Construct a Credentials object and return it in a callback to SDK
import Sensibill

class CustomTokenProvider: TokenProvider {

    /// TokenProvider implementation
    func provideTokenReplacement(userIdentifier: String, completion: @escaping (Credentials?, Error?) -> Void) {
        
        // Step 1: (Recommended) Ensure the requested token is for currently authenticated user
        guard userIdentifier == <current user identifier> else {
            completion(nil, Errors.userIdentifierMismatch)
            return
        }

        // Step 2: Obtain a token from your integration server
        var request = URLRequest(...)
        let task = URLSession.shared.dataTask(with: request) { (data, response, error) in

            // Step 3: Process the response from your authentication server

            // 3.1 Check for errors. If error is returned, pass this error in callback to SDK:
            if error != nil {
                completion(nil, error)
                return
            }

            // 3.2 Parse the response to ensure the access token was obtained
            guard let accessToken = // ... else {
                completion(nil, Errors.accessTokenWasNotProvided)
                return
            }

            // 3.3 Construct a Credentials object and return it in a callback to SDK:
            let credentials = Credentials(accessToken: accessToken)
            completion(credentials, nil)
        }
        task.resume()
    }
}

extension CustomTokenProvider {
    
    enum Errors: Error {
        case userIdentifierMismatch
        case accessTokenWasNotProvided
    }
}

An instance of the token provider must be passed to the SDK on SensibillSDK.start. See Launching the SDK section below for further information.