Network Client
By default each Descope mobile SDK performs its own HTTP requests using the platform's standard networking stack. The Swift, Kotlin, and Flutter SDKs let you replace that stack with your own implementation by setting a network client on the SDK configuration.
When to Use It
- Unit testing. Supply a client that returns canned responses or throws, so tests that exercise your Descope integration make no real network calls.
- Reusing your app's HTTP stack. Route Descope requests through the same session, connection pool, or client instance the rest of your app already uses.
- Instrumentation. Observe request timing or attach your own tracing around the calls the SDK makes.
Implementing a Network Client
Each platform defines the client differently, so the method you implement and the values you return are not the same across SDKs.
DescopeNetworkClient is a protocol with a single method whose signature intentionally matches URLSession.data(for:).
public protocol DescopeNetworkClient: Sendable {
func call(request: URLRequest) async throws -> (Data, URLResponse)
}Set it when you configure the SDK:
Descope.setup(projectId: "__ProjectID__") { config in
config.networkClient = AppNetworkClient(appSession)
}To reuse an existing URLSession from elsewhere in your app:
class AppNetworkClient: DescopeNetworkClient {
let session: URLSession
init(_ session: URLSession) {
self.session = session
}
func call(request: URLRequest) async throws -> (Data, URLResponse) {
return try await session.data(for: request)
}
}To make sure no network calls happen at all during a test:
final class FailingNetworkClient: DescopeNetworkClient {
let error: DescopeError = .networkError
func call(request: URLRequest) async throws -> (Data, URLResponse) {
throw error
}
}DescopeNetworkClient is an interface with a suspending method. Unlike Swift and Flutter, it receives the request as separate arguments and returns a Response object rather than a platform HTTP type.
interface DescopeNetworkClient {
suspend fun sendRequest(
url: URL,
method: String,
body: Map<String, Any?>?,
headers: Map<String, String>,
): Response
class Response(
val code: Int,
val body: String,
val headers: Map<String, List<String>>,
)
}The method argument is an uppercase HTTP method such as "GET" or "POST". Set the client when you configure the SDK:
Descope.setup(this, projectId = "__ProjectID__") {
networkClient = AppNetworkClient()
}A client that fails every request, so a test makes no real network calls:
class FailingNetworkClient : DescopeNetworkClient {
override suspend fun sendRequest(
url: URL,
method: String,
body: Map<String, Any?>?,
headers: Map<String, String>,
): DescopeNetworkClient.Response {
throw IOException("network disabled in tests")
}
}DescopeNetworkClient is an abstract class built around the http package types.
abstract class DescopeNetworkClient {
Future<http.Response> sendRequest(http.Request request);
}Set it when you configure the SDK:
Descope.setup('__ProjectID__', (config) {
config.networkClient = AppNetworkClient();
});A client that fails every request, so a test makes no real network calls:
class FailingNetworkClient extends DescopeNetworkClient {
@override
Future<http.Response> sendRequest(http.Request request) async {
throw Exception('network disabled in tests');
}
}The React Native SDK has no DescopeNetworkClient. Pass a fetch implementation to AuthProvider instead, and it is used for the requests the SDK makes from JavaScript:
<AuthProvider projectId="__ProjectID__" fetch={customFetch}>
<App />
</AuthProvider>customFetch must have the same signature as the global fetch.