Configuring Advanced Features

In this segment we will explore more advanced topics that will help you get the most out of the SDK.


The AppID is the key to start the PerimeterX SDK, by calling the PerimeterX/start(appId:delegate:enableDoctorCheck:completion:) function with it. If you are using only one AppID in your app, all other functions in the SDK will work properly without specifying the AppID again (you may pass nil).


The PerimeterXDelegate provides callbacks, such as request blocked or challenge solved. However, The delegate can be set only once when calling the PerimeterX/start(appId:delegate:enableDoctorCheck:completion:) function. You can set that more objects in your project to receive those callbacks too. Use the PerimeterX/registerCallbackForRequestBlockedEvent(forAppId:callback:) and the PerimeterX/registerCallbackForChallengeSolvedEvent(forAppId:callback:) functions. Here is an example:

let requestBlockedEventRegistrationId = PerimeterX.registerCallbackForRequestBlockedEvent {
    print("PerimeterX Request Blocked")

let challengeSolvedEventRegistrationId = PerimeterX.registerCallbackForChallengeSolvedEvent(callback: {
    print("PerimeterX Challenge Solved")
NSString *requestBlockedEventRegistrationId = [PerimeterX registerCallbackForRequestBlockedEventForAppId:nil callback:^{
    NSLog(@"Request Blocked Event");

NSString *challengeSolvedEventRegistrationId = [PerimeterX registerCallbackForChallengeSolvedEventForAppId:nil callback:^{
    NSLog(@"Challenge Solved Event");

The PerimeterX/registerCallbackForRequestBlockedEvent(forAppId:callback:) and the PerimeterX/registerCallbackForChallengeSolvedEvent(forAppId:callback:) functions return a Registration ID. Use it to unregister from getting those callbacks with PerimeterX/unregisterCallbackForRequestBlockedEvent(forAppId:registrationId:) and PerimeterX/unregisterCallbackForChallengeSolvedEvent(forAppId:registrationId:) functions. Here is an example:

PerimeterX.unregisterCallbackForRequestBlockedEvent(forAppId: nil, registrationId: requestBlockedEventRegistrationId)

PerimeterX.unregisterCallbackForChallengeSolvedEvent(forAppId: nil, registrationId: challengeSolvedEventRegistrationId)
[PerimeterX unregisterCallbackForRequestBlockedEventForAppId:nil registrationId:requestBlockedEventRegistrationId];

[PerimeterX unregisterCallbackForChallengeSolvedEventForAppId:nil registrationId:challengeSolvedEventRegistrationId];

Another important callback is when the Perimeter SDK is ready. Calling the PerimeterX/start(appId:delegate:enableDoctorCheck:completion:) function will start an async operation that will start the PerimeterX SDK. This function has a completion handler, but you can register to this event from other places in your project, using the PerimeterX/addInitializationFinishedCallback(forAppId:callback:) function. Here an example:

PerimeterX.addInitializationFinishedCallback(forAppId: nil) {
    print("PerimeterX is ready")
[PerimeterX addInitializationFinishedCallbackForAppId:nil callback:^{
    NSLog(@"PerimeterX is ready");

You can call the PerimeterX/addInitializationFinishedCallback(forAppId:callback:) when the PerimeterX SDK is ready. In this case, the callback will be called immediately.

Block Error

When the PXPolicy/requestsInterceptedAutomaticallyEnabled is set to true, the PerimeterX SDK will automatically block requests and present a challenge to the end user. When there is a block, the original request will fail with the following Error: domain: PerimeterXErrorDomain, code: PerimeterXErrorCode/requestWasBlocked. You can check the received error with the PerimeterX/isRequestBlockedError(error:) function. Here an example:

let isRequestBlockedError = PerimeterX.isRequestBlockedError(error: error)
if isRequestBlockedError {
    print("request was blocked by PX")
BOOL isRequestBlockedError = [PerimeterX isRequestBlockedErrorWithError:error];
if (isRequestBlockedError) {
    NSLog(@"request was blocked by PX");

Hybrid App

The hybrid App uses both native URL requests and web views to communicate with the server. In the context of PerimeterX, it's important to make sure both native requests and web views are synced together to make sure end users will get the expected behavior from your app. To help PerimeterX SDK achieve that, you should set your domain in the policy for the relevant AppID. Here an example:

let policy = PXPolicy()"")
PerimeterX.setPolicy(policy: policy, forAppId: nil, completion: nil)
PXPolicy *policy = [[PXPolicy alloc] init]; = [NSSet setWithObject:@""];
[PerimeterX setPolicyWithPolicy:policy forAppId:nil completion:nil];

Multiple AppIDs

You can configure multiple AppIDs for the PerimeterX SDK, by calling the PerimeterX/start(appId:delegate:enableDoctorCheck:completion:) function for each AppID you have.

When using multiple AppIDs, you should:

  1. Specify the relevant AppID anytime you call functions in the PerimeterX SDK.
  2. Set the domain list in the policy for each AppID. Here is an example:
let policyForAppId1 = PXPolicy()"")
    PerimeterX.setPolicy(policy: policyForAppId1, forAppId: "<APP_ID_1>", completion: nil)

    let policyForAppId2 = PXPolicy()"")
    PerimeterX.setPolicy(policy: policyForAppId2, forAppId: "<APP_ID_2>", completion: nil)
PXPolicy *policyForAppId1 = [[PXPolicy alloc] init]; = [NSSet setWithObject:@""];
    [PerimeterX setPolicyWithPolicy:policyForAppId1 forAppId:@"<APP_ID_1>" completion:nil];

    PXPolicy *policyForAppId2 = [[PXPolicy alloc] init]; = [NSSet setWithObject:@""];
    [PerimeterX setPolicyWithPolicy:policyForAppId2 forAppId:@"<APP_ID_2>" completion:nil];

Doctor App

The "Doctor App" is a tool that helps verify the SDK integration in your project by simulating a typical user flow in the application. When the "Doctor app" is enabled, it will pop up as part of the app flow and will guide the developer on simulating a user flow to gather the required information for testing the integration.
In order to enable this feature, call the PerimeterX/start(appId:delegate:enableDoctorCheck:completion:) function with the enableDoctorCheck as true. Here is an example:

PerimeterX.start(appId: "<APP_ID>", delegate: self, enableDoctorCheck: true) { success, error in
[PerimeterX startWithAppId:@"<APP_ID>" delegate:self enableDoctorCheck:YES completion:^(BOOL success, NSError * _Nullable error) {



Important Notice

This feature is for development only and should not be shipped as enabled with the application to the store.


  1. Welcome screen
    In this screen you select whether to start a new test or load the summary of a previous test, if one exists.
  1. Instruction screen
    In this screen you get a detailed explanation on how to start a new test, what is expected to happen and what you can do in case you are not able to generate a challenge/captcha.
  1. Test selection screen
    In this screen you can select between two different types of tests:
    1. Native app framework - to test your native URL requests.
    2. Web view framework - to test your web view URL requests.
      When you are done executing a test, you will return to this screen to enable you to start the other test.
  1. Summary screen
    In this screen you review the test results. You can go into details regarding each test and get troubleshooting tips in case a test failed, to help you analyze what is causing this issue.


Please Note

When you exit the doctor app, your app will also terminated. Just remember to switch the enableDoctorCheck param to false in case you finished validating your SDK integration.

Enable Account Defender

In order to enable Account Defender, a user ID should be set. You can set it by calling the PerimeterX/setUserId(userId:forAppId:) function.

PerimeterX.setUserId(userId: "<the current user ID>", forAppId: nil)
[PerimeterX setUserIdWithUserId:@"<the current user ID>" forAppId:nil];

When the current user logs out, you should call this function again with nil. This will turn off the Account Defender supported features.

To inform Account Defender about the user flow, call this function for each URL request that's been send to your server. Notice that when the interceptor is enabled, this is done automatically by the SDK and there is no need to manually call the function.

PerimeterX.registerOutgoingUrlRequest(url: "<URL>", forAppId: nil)
[PerimeterX registerOutgoingUrlRequestWithUrl:@"<URL>" forAppId:nil];

Did this page help you?