Orchestration SDKs

Customizing requests from the Journey module on iOS

PingOne Advanced Identity Cloud PingAM iOS

All modules in the Orchestration SDK for iOS use an HTTP client abstraction provided by the PingNetwork module to make network requests.

You can use this HTTP client to create interceptors, that can modify requests before they’re sent, or inspect responses after they’re received.

For example, you can add or customize:

  • Query parameters

  • Headers

  • Cookies

  • Body data

You can add the commonly-used forceAuth and noSession query parameters when starting a journey, without creating an interceptor.

Step 1. Creating an HTTP client

To customize network requests, initialize and configure an HttpClient instance:

Initializing HttpClient on iOS
import PingNetwork

let customHttpClient = HttpClient.createClient { config in
    // Optional: Configure timeout (default: 15 seconds)
    config.timeout = 30.0
    // Optional: Configure logging (default: LogManager.logger)
    config.logger = LogManager.warning
}

Use the following properties to configure the HTTP client:

timeout

The number of seconds to wait before each request times out.

Default is 15 seconds.

logger

The logger that HttpClient uses for output.

Available options are:

Value Description

LogManager.standard

Outputs all log messages to the console.

LogManager.warning

Outputs only warning and error log messages to the console.

LogManager.none

Prevents all log messages.

LogManager.logger

Use whichever logger is already configured in the application.

Default is LogManager.logger.

Step 2. Adding interceptors to the HTTP client

Add custom interceptors to the HTTP client to modify requests before they’re sent or inspect responses after they’re received.

Adding request interceptors

To add an interceptor that applies to all outgoing requests from a module, use the onRequest method.

To customize the requests, pass in your own values for headers, query parameters, cookies, or body parameters.

  • Headers

  • Query parameters

  • Cookies

  • Body data

Customizing headers using request interceptors in HttpClient
let customHttpClient = HttpClient.createClient { config in
    // Add authentication token to all requests
    config.onRequest { request in
        request.setHeader(name: "Authorization", value: "Bearer \(token)")
    }

    // Add custom user agent
    config.onRequest { request in
        request.setHeader(name: "User-Agent", value: "MyApp/1.0")
    }
}
Customizing query parameters using request interceptors in HttpClient
let customHttpClient = HttpClient.createClient { config in
    // Add custom query parameters
    config.onRequest { request in
        request.setParameter(name: "lang", value: "en-UK")
        request.setParameter(name: "brand", value: "example.co.uk")
    }
}
Customizing cookies using request interceptors in HttpClient
let customHttpClient = HttpClient.createClient { config in
    // Add a single cookie
    config.onRequest { request in
        request.setCookie(cookie: "sessionId=abc123")
    }

    // Add multiple cookies
    config.onRequest { request in
        request.setCookies(cookies: ["sessionId=abc123","custId=036883763"])
    }
}
Customizing body data using request interceptors in HttpClient
let customHttpClient = HttpClient.createClient { config in
    // Add JSON body data to a POST request
    config.onRequest { request in
        request.post(json: [
            "name": "John Doe",
            "email": "john@example.com"
        ])
    }

    // Add JSON body data to a PUT request
    config.onRequest { request in
        request.put(json: [
            "name": "Updated Name",
            "email": "updated@example.com"
        ])
    }

    // Add form-encoded body data to a POST request
    config.onRequest { request in
        request.form(parameters: [
            "name": "John Doe",
            "email": "john@example.com"
        ])
    }
}

Adding response interceptors

To add an interceptor that can inspect all incoming responses to a module, use the onResponse method.

To inspect the response, capture the values of the incoming headers, cookies, body parameters, and HTTP response status.

You can also capture the original request object that triggered the response, which can be useful for auditing or debugging purposes.

  • HTTP Status

  • Headers

  • Cookies

  • Body data

  • Original request

Capturing HTTP status codes using response interceptors in HttpClient
let customHttpClient = HttpClient.createClient { config in
    // Use convenience methods on HTTP status code of a response
    config.onResponse { response in
        if response.status.isSuccess() {
            // 2xx status code
        } else if response.status.isRedirect() {
            // 3xx status code
        } else if response.status.isClientError() {
            // 4xx status code
        } else if response.status.isServerError() {
            // 5xx status code
        }
    }
}
Capturing headers using response interceptors in HttpClient
let customHttpClient = HttpClient.createClient { config in
    // Get all headers
    config.onResponse { response in
        let allHeaders = response.headers
    }

    // Get individual header
    config.onResponse { response in
        if let contentType = response.getHeader(name: "Content-Type") {
            print("Content-Type: \(contentType)")
        }
    }
}
Capturing cookies using response interceptors in HttpClient
let customHttpClient = HttpClient.createClient { config in
    // Get an array of all cookies
    config.onResponse { response in
        let cookies = response.getCookies()
    }

    // Get an array of raw cookie strings
    // Example:
    // [“interactionId=18ee2327-0766-4314-94d6-297402589bff; Path=/; Expires=Fri, 24 Apr 2026 14:15:31 GMT; HttpOnly; Secure; SameSite=None”]
    config.onResponse { response in
        let cookieStrings = response.getCookieStrings()
    }
}
Capturing body data using response interceptors in HttpClient
let customHttpClient = HttpClient.createClient { config in
    // Get body data as a string
    config.onResponse { response in
        let bodyString = response.bodyAsString()
    }

    // Get body as raw data type
    config.onResponse { response in
        if let bodyData = response.body {
            let json = try? JSONSerialization.jsonObject(with: bodyData)
        }
    }
}
Capturing the original request that caused a response
let customHttpClient = HttpClient.createClient { config in
    // Capture the original outgoing request
    config.onResponse { response in
        let originalRequest = response.request
    }
}

Step 3. Configuring the Journey module to use an HTTP client

Pass the name of your custom HTTP client to the Journey module in the httpClient parameter in the configuration:

Configuring the journey module
let journey = Journey.createJourney { config in
    // Custom HTTP client
    config.httpClient = customHttpClient

    // Other configuration
    config.serverUrl = "https://openam-forgerock-sdks.forgeblocks.com/am"
    config.realm = "alpha"
    config.cookie = "ch15fefc5407912"
    config.logger = LogManager.standard
}

Step 4. Cleaning up an HTTP client

To help manage resources the HTTP client might use, call close() on the client when you have finished with it.

Closing an HTTP client
customHttpClient.close()