Custom API requests

UsherSDK provides several low level apis for performing network api requests. These apis can be used either to perform api requests to Usher server that are not supported by default in the UsherSDK, or perfom requests and implement custom handling of responses. The following cases explains ways of making api requests to Usher server.

Note:

Before considering using these apis, carefully evaluate if your requirement is not already supported by UsherSDK. Although it is possible to make these requests, there are lots of additional steps and optimizations done by UsherSDK Managers and Services in addition to making the api requests such as automatic caching, notifying observers and custom response parsing logics. So only use these apis in use cases the UsherSDK has no support for.

1. Using UsherAPIRequest and UsherAPITask

The first and effortless way of making api requests is using an UsherAPIRequest initialized with an UsherAPITask. UsherAPITask defines several api request tasks that will be used to configure the UsherAPIRequest. UsherAPIRequest is the best way of making requests since it supports automatic dynamic pinning of server certificate and client certificate authentication.

An UsherAPIRequest can be initialized as shown in the code snippets below. ( See UsherAPITask documentation for a full list of supported api requests tasks. )

// initialize a request for fetching badge detail for a specific badge id
let fetchBadgeRequest = UsherAPIRequest(for: .Badge(id: "1234567"))

// initialize a request for fetching keys for a specific badge
let fetchKeysRequest = UsherAPIRequest(for: .KeysForBadge(id: "1234567"))

// initialize a request for requesting recovery code by email for a user
let codeRecoveryRequest = UsherAPIRequest(for: .RetrieveRecoveryCodeForEmail(email: "jhon.smith@example.com"))

Initializing UsherAPIRequest with a task will automatically configure the request with all the required parametes and headers by Usher server. After creating the requests, you can excute them as shown in the code snippet bellow

// Set response handling closure. The closure is called with a response json object of type 
// SwiftJSON.JSON if request was successful or an `APIResponseError` instance if request failed.
fetchBadgeRequest.responseJSON { json, error in

    guard let json = json, error == nil else {
        // handle error
        return
    }

    //initialize a badge object with the json object.
    let badge = Badge(json: json)

    // ...
}

// Start the request. 
fetchBadgeRequest.start()

Alternatively, the raw data response object can be received from the request execution as shown below. However, it is highly recommended to use the default initializer with JSON for models provided by UsherSDK. Do custom parsing for model objects and responses only if it is not supported by UsherSDK.

// Set response handling closure. The closure is called with a response data object
// if request was successful or an `APIResponseError` instance if request failed.
fetchBadgeRequest.responseJSON { data, error in

    guard let data = data, error == nil else {
        // handle error
        return
    }

    // Do custom parsing of the respose data here ... 

}

// Start the request. 
fetchBadgeRequest.start()

2. Using UsherAPIRequest and UsherAPIRequestConfiguration

This is a bit more advanced way of making api requests to Usher server. This is also handy when making api requests that are not supported by Usher SDK. UsherAPIRequestConfiguration is a class conforming to APIRequestConfigurationType. UsherAPIRequestConfiguration adds implementations for automatic configuration with UsherAPITask and also automatic configuration of properties required by Usher server such as access token, location, device and OS info, locale, timezone and time. UsherAPIRequestConfiguration also adds implementations for URLConvertibleand URLRequestConvertible protocols to effortlessly format the request as a URL and configuring a URLRequest object. Using UsherAPIRequestConfiguration lifts the burden of configuring all the reccuring api request parameters sent with every query and lets you configure only the parameters specfic to your request.

To make an api request with a custom configuration object, first create an UsherAPIRequestConfiguration as shown below

// Create and UsherAPIRequestConfiguration instance
var config = UsherAPIRequestConfiguration()

// Set values for the configuration. See full list of configuration in `UsherAPIRequestConfiguration`'s documentation.
config.path = "/badge/1234567"
config.method = .get
config.parameters = [(URLEncoding(destination: .queryString), ["current_badge_id": "1234567"])]

// Initialize an UsherAPIRequest with the configuration.
let request = UsherAPIRequest(with: config)
request.responseJSON { (json, error) in
    // handle request response here.
}

// Start the request. 
request.start()

In the above snippet, since no server and device is specified, the UsherAPIRequest automatically use the default configured server for the SDK and the device for the server instance. The request will also automatically handle dynamic pinning of server certificate and client certificate authentication. However, in unlikely case that you want to provide your own usher server and device instances, UsherAPIRequestConfiguration can be initialized with UsherAPIRequestConfiguration.init(with:and:) .

3. Using APIRequest and custome configuration conforming to APIRequestConfigurationType protocol

This third case is very advanced and relatively hard to implement. In the previous examples, we have seen how UsherAPIRequestConfiguration is an implementation of APIRequestConfigurationType protocol. Although not recommended, another custom configuration can be created by conforming to APIRequestConfigurationType. When doing so you have to be sure to provide all the required parameters.

Same way as how UsherAPIRequestConfiguration simplifies making api requests, UsherAPIRequest subclasses APIRequest and adds several important helpers. The most prominent once are automatic support for dynamic pinning of server certificate and client certificate authentication. If for some reason you are not able to use UsherAPIRequest, you can create an instance of APIRequest directly, but that would mean you’ll have to manually handle providing dynamic pinning and client certificates.