Installing the SDK


The following are required to install the PerimeterX iOS SDK:

  1. Administrative access to the PerimeterX Portal to:

    1. Retrieve the PerimeterX application ID (AppID).

    2. Set the token expiration and validity.

  2. An active PerimeterX Enforcer.


Choose the PerimeterX SDK version according to your development environment:

Xcode 13.4
Swift 5.6
Xcode 13.3
Swift 5.6
Xcode 13.0 - 13.2
Swift 5.5

Adding PerimeterX SDK to your project with:

Swift Package Manager

Add the package from the following repository:


Add the PerimeterX pod to your Podfile:

platform :ios, '13.0'

target '<Your App Name>' do
    pod 'PerimeterX', '<Version>'


  1. Download PerimeterX_SDK.xcframework from

  2. In Xcode, add the framework to the "Frameworks and Libraries" section in your target.


In your AppDelegate:

  1. Import the SDK.
import PerimeterX_SDK
@import PerimeterX_SDK;
  1. Make the AppDelegate class to conform to the PerimeterXDelegate.
class AppDelegate: UIResponder, UIApplicationDelegate, PerimeterXDelegate
@interface AppDelegate : UIResponder <UIApplicationDelegate, PerimeterXDelegate>
  1. Verify the SDK's version.
print("SDK version: \(PerimeterX.sdkVersion())")
NSLog(@"SDK version: %@", [PerimeterX sdkVersion]);
  1. Call the PerimeterX's start function with your AppID in the UIApplicationDelegate's didFinishLaunchingWithOptions function. This function sets up the session for a given AppID. When the process ends, and the completion handler is called with success as true, the SDK will have an updated token from PerimeterX backend. However, while this function is working in the background, the SDK will still provide the required headers (for example, a token from a previous session if exists). It's essential to call this function as early as possible in your application and before any URL request to your server.
PerimeterX.start(appId: "<APP_ID>", delegate: self, enableDoctorCheck: false) { success, error in
        if success {
            if let vid = PerimeterX.vid(forAppId: nil) {
                print("vid: \(vid)")
        else {
            if let error = error {
                print("error: \(error)")
            // make sure to start the sdk again when it fails (network issue, etc.)
[PerimeterX startWithAppId:@"<APP_ID>" delegate:self enableDoctorCheck:NO completion:^(BOOL success, NSError * _Nullable error) {
        if (success) {
            NSString *vid = [PerimeterX vidForAppId:nil];
            NSLog(@"vid: %@", vid);
        else {
            NSLog(@"error: %@", error);
            // make sure to start the sdk again when it fails (network issue, etc.)
  1. That's it! 🎉 You can follow this link and download our demo app in order to see an example of integrating the SDK in an iOS app.

Disable automatic interception

The SDK automatically intercepts HTTP requests and adds relevant HTTP headers. However, you can disable this and add those HTTP headers manually.

  1. After calling the PerimeterX's start function, disable the automatic interception in the policy. In order that the new policy will be taken into affect, you must call the start function before setting the new policy. It's recommended to set the policy right after calling the start function to avoid unexpected behaviour. You don't have to wait until the completion handler of the start function is called, before you set the policy.
let policy = PXPolicy()
policy.requestsInterceptedAutomaticallyEnabled = false
PerimeterX.setPolicy(policy: policy, forAppId: nil, completion: nil)
PXPolicy *policy = [[PXPolicy alloc] init];
policy.requestsInterceptedAutomaticallyEnabled = NO;
[PerimeterX setPolicyWithPolicy:policy forAppId:nil completion:nil];
  1. Before sending your URL request, take HTTP headers from the SDK and add them to your request. The SDK should always return headers. When no headers are returned, it means that something went wrong with the SDK integration.
let headers = PerimeterX.headersForURLRequest(forAppId: nil)
NSDictionary<NSString *, NSString *> *headers = [PerimeterX headersForURLRequestForAppId:nil];
  1. After receiving an error in the response, pass the information to SDK.
let isHandledByPX = PerimeterX.handleResponse(forAppId: nil, data: data, response: response)
if isHandledByPX {
  print("block response was handled by PX")
BOOL isHandledByPX = [PerimeterX handleResponseForAppId:nil data:data response:response];
if (isHandledByPX) {
  NSLog(@"block response was handled by PX");

Integration with React Native

The Perimeter X iOS SDK can be integrated into React Native projects.

  1. Add the SDK to your Android project as described above.
  2. The automatic interceptor is not supported in React Native, so any request from the JavaScript code has to be handled manually.
  3. Disable the automatic interception as described above.
  4. Create a native module as described here.
  5. Create a function that pass the HTTP headers from the PerimeterX SDK to the JavaScript code. Here is an example:
RCT_EXPORT_METHOD(getHTTPHeaders:(RCTResponseSenderBlock)callback) {
  NSDictionary<NSString *, NSString *> *headers = [PerimeterX headersForURLRequestForAppId:nil];
  NSData *data = [NSJSONSerialization dataWithJSONObject:headers options:0 error:nil];
  NSString *json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  1. In your JavaScript code, send your request with those HTTP headers. Here is an example:
PerimeterXModule.getHTTPHeaders(async headers => {  
  const obj = JSON.parse(headers);
  const url = ''
  const response = await fetch(url, {  
    method: 'GET',  
    headers: obj,  
  1. Next, pass the response back to the native module. Here is an example:
RCT_EXPORT_METHOD(handleResponse:(NSString *)response code:(NSInteger)code url:(NSString *)url) {
  NSData *data = [response dataUsingEncoding:NSUTF8StringEncoding];
  NSHTTPURLResponse *httpURLResponse = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:url] statusCode:code HTTPVersion:nil headerFields:nil];
  [PerimeterX handleResponseForAppId:nil data:data response:httpURLResponse];
const json = await response.json();  
PerimeterXModule.handleResponse(JSON.stringify(json), response.status, url);

Migrating from earlier SDK version (1.x)

Start the SDK

In version 1.x, the start function is called with two parameters: AppId and enableDoctorCheck (the later was added in 1.16.0).

In version 2.0, the start function has additional parameters:

  1. delegate (PerimeterXDelegate) to handle the SDK's events.
  2. completion handler to handle the result of the start process.

Notice that the new Interceptor will be enabled in 2.0. This has effect on the integration with the SDK, which is described in this document.

Set custom parameters

In version 1.x, the set custom parameters function is called with the dictionary parameter only.

In version 2.0, the setCustomParameters function has another optional param: the AppID. This is required only when using multiple AppIDs.


In version 1.x, the get VID function is called without any parameters.

In version 2.0, the vid function has another optional param: the AppID. This is required only when using multiple AppIDs.

Get HTTP headers

In version 1.x, the get HTTP headers function is called without any parameters.

In version 2.0, the headersForURLRequest function has another optional param: the AppID. This is required only when using multiple AppIDs.



The Get HTTP headers function should NOT be used when the interceptor is enabled.

Check error and handle response

In version 1.x, a function is called to get the PX's error response from the request's response which called another function to handle the PX's error response.

In version 2.0 the flow is as following:

  1. If the interceptor is enabled, simply check whether the request was blocked with the isRequestBlockedError function
  2. If the interceptor is disabled, use the PerimeterX SDK to handle the response with the handleResponse function. If it was a blocked response, the SDK will handle it and the function will return true

Other functions

All other functions existing in version 1.x were removed from the SDK's API in version 2.0.

Did this page help you?