DataDomeApollo 3.6.2

DataDomeApollo 3.6.2

Maintained by DataDome Mobile Team.



 
Depends on:
Apollo~> 1.0
DataDomeSDK~> 3.6.2
 

  • By
  • DataDome

DataDome Apollo Integration

Version License Platform

Installation

Swift package manager

The DataDomeApollo SDK is available on Swift Package Manager. To get the SDK integrated to your project:

  1. In Xcode > File > Swift Packages > Add Package Dependency, select your target in which to integrate DataDomeApollo.
  2. Paste the following git url in the search bar https://github.com/DataDome/datadome-Apollo-package
  3. Select DataDomeApollo and press Add.

Cocoapods

If your api is a GraphQL api, the chances are that you are using Apollo SDK. If so, we have a dedicated framework called DataDomeApollo designed to ease the DataDome SDK integration.

To install the plugin, use the following Cocoapods instruction: Alternatively, DataDomeAlamofire is available on CocoaPods. To get the SDK integrated to your project, simply add the following line to your Podfile:

pod "DataDomeApollo"

Run pod install to download and integrate the framework to your project.

Getting started

  1. Run your application. It is going to crash with the following log
Fatal error: [DataDome] Missing DataDomeKey (Your client side key) in your Info.plist
  1. In your Info.plist, add a new entry with String type, use DataDomeKey as key and your actual client side key as value.
  2. In your Info.plist, add a new entry with Boolean type, use DataDomeProxyEnabled as key and NO as value. This will disable method swizzling in the framework.
  3. You can run now the app, it won't crash. You should see a log confirming the SDK is running
[DataDome] Version x.y.z

Congrats, the DataDome and DataDomeAlamofire frameworks are well integrated

Logging

If you need to see the logs produced by the framework, you can set the log level to control the detail of logs you get

import DataDome
DataDome.setLogLevel(level: .verbose)

By default, the framework is completely silent.

The following table contains different logging levels that you may consider using

Level Description
verbose Everything is logged
info Info messages, warnings and errors are shown
warning Only warning and errors messages are printed
error Only errors are printed
none Silent mode (default)

Force a captcha display

You can simulate a captcha display using the framework by providing a user agent with the value BLOCKUA

To do so:

  1. Edit your app scheme
  2. Under Run (Debug) > Arguments > Environment Variables, create a new variable
  3. Set the name to DATADOME_USER_AGENT and the value to BLOCKUA

The DataDome framework will inject the specified user agent in the requests the app will be sending. Using the BLOCKUA user agent value will hint our remote protection module installed on your servers to treat this request as if it is coming from a bot. Which will block it with a captcha response.

Since the DataDome framework retains the cookies after resolving the captcha, this test can be done only the first time you used the BLOCKUA user agent. To reproduce the test case, you can use the following code snippet to manually clear the cookies stored in your app

for cookie in HTTPCookieStorage.shared.cookies ?? [] {
    HTTPCookieStorage.shared.deleteCookie(cookie)
}

Apollo Integration

We use the Interceptor pattern built in the Apollo SDK to make sure we intercept all requests and protect them. The following is the init of the DataDome Interceptor


let interceptor = DataDomeResponseInterceptor()

The interceptor could be used then in your pipeline. It will intercept all requests, catch requests blocked by DataDome, display the captcha and eventually retry the request automatically once the captcha is resolved.

####Important The order in defining the interceptors is important in Apollo. Make sure the DataDome response Interceptor is the first interceptor after the NetworkFetchInterceptor.

Alternatively, you can use the DataDomeInterceptorProvider which is a pre-built sequence of interceptors ready to be used by your app. This provider is providing the same interceptors as the Legacy Interceptor provider. You can customise the interceptors to be added in the provider or use the default set.

// Create your own store needed to init the DataDomeInterceptor provider
let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)

// Use DataDomeURLSessionClient to enable updating the user-agent
let client = DataDomeURLSessionClient()

// Create the DataDome Interceptor Provider
let provider = DataDomeInterceptorProvider(store: store, client: client)

// Create your GraphQL URL
guard let url = URL(string: "YOUR_ENDPOINT") else {
    fatalError("Unable to create url")
}

let requestChainTransport = RequestChainNetworkTransport(interceptorProvider: provider,
                                                         endpointURL: url)

// Create the client with the request chain transport
return ApolloClient(networkTransport: requestChainTransport,
                    store: store)
}()

In the above exemple we used the default configuration of DataDomeInterceptorProvider. You can specify custom interceptors using the following init method

/// - Parameters:
///   - store: The apollo store
///   - client: The URLSession client
///   - preFetchInterceptors: The list of interceptors to go before the fetch operation
///   - fetchInterceptor: The fetch operation
///   - postFetchInterceptors: The list of interceptors to go after the fetch operation
public init(store: ApolloStore,
            client: URLSessionClient,
            preFetchInterceptors: [ApolloInterceptor] = [],
            fetchInterceptor: ApolloInterceptor? = nil,
            postFetchInterceptors: [ApolloInterceptor] = [])

preFetchInterceptors is a set of interceptors to be added before firing the request. By default we add: CacheReadInterceptor

fetchInterceptor is the interceptor that will execute the request. By default, we use: NetworkFetchInterceptor

The DataDomeResponseInterceptor is then added to the chain just after the fetch interceptor.

postFetchInterceptors is a set of interceptors to be added after the fetch interceptor. By default we add: - ResponseCodeInterceptor - JSONResponseParsingInterceptor - AutomaticPersistedQueryInterceptor - CacheWriteInterceptor