How to integrate the SDK in your application
v2.x
Introducing the software documentation and the demo app!
The software documentation provides elaborated information on every class, function and member in the SDK. The class documentation is a .doccarchive
file that can be opened with Xcode. To get it, please follow those steps:
- Open the tag list in the SDK repo.
- Select the wanted version.
- Download the source code (zip file).
- Unzip the file and open the
PerimeterX_SDK.doccarchive
file via Xcode.
The demo app gives you a general idea on how you should implement the SDK in you app. To download it, please follow those steps:
- Open the demo app repo.
- Download the content of the repo.
- Unzip the file and open the iOS demo app.
Prerequisites
The following are required to install the SDK:
- Administrative access to the HUMAN Portal to:
- Retrieve the HUMANÂ application ID (AppID).
- Set the token expiration and validity.
- An active HUMAN Enforcer.
Choose the HUMAN SDK version according to your development environment:
Xcode 15.1
Swift 5.9
Xcode 13.4
Swift 5.6
Xcode 13.3
Swift 5.6
Xcode 13.0 - 13.2
Swift 5.5
Adding HUMAN SDK to your project:
You can add the SDK to your project with one of the following options:
Swift Package Manager
Add the package from the following repository: https://github.com/PerimeterX/px-iOS-Framework
CocoaPods
Add the HUMAN pod to your Podfile.
platform :ios, '13.0'
use_frameworks!
target '<Your App Name>' do
pod 'PerimeterX', '<version>'
end
Manual
- Open the SDK repo.
- Download the content of the repo.
- Unzip the file and copy the
PerimeterX_SDK.xcframework
file to you project. - In Xcode, add the framework to the "Frameworks and Libraries" section in your target.
How to start the SDK
Starting the SDK should be the first thing that runs in your app. Therefore, you should start it in your AppDelegate
class:
-
Import the SDK.
import PerimeterX_SDK
@import PerimeterX_SDK;
-
Make the
AppDelegate
class to conform to thePerimeterXDelegate
. Implement all functions in the protocol.class AppDelegate: UIResponder, UIApplicationDelegate, PerimeterXDelegate
@interface AppDelegate : UIResponder <UIApplicationDelegate, PerimeterXDelegate>
-
Call the
PerimeterX/start(appId:delegate:enableDoctorCheck:completion:)
function with your AppID in theUIApplicationDelegate
'sdidFinishLaunchingWithOptions
function.PerimeterX.start(appId: "<APP_ID>", delegate: self, enableDoctorCheck: false) { success, error in if !success { // 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) { // make sure to start the sdk again when it fails (network issue, etc.) } }];
-
You can set the SDK's policy to configure custom configurations and behaviors:
let policy = PXPolicy() // configure the policy instacne PerimeterX.setPolicy(policy: policy, forAppId: nil, completion: nil)
PXPolicy *policy = [[PXPolicy alloc] init]; // configure the policy instacne [PerimeterX setPolicyWithPolicy:policy forAppId:nil completion:nil];
That's it! 🎉 Your code should be like this:
PerimeterX.start(appId: "<APP_ID>", delegate: self, enableDoctorCheck: false) { success, error in
if !success {
// start the sdk again when it fails (network issue, etc.)
}
}
let policy = PXPolicy()
// configure the policy instacne
PerimeterX.setPolicy(policy: policy, forAppId: nil, completion: nil)
[PerimeterX startWithAppId:@"<APP_ID>" delegate:self enableDoctorCheck:NO completion:^(BOOL success, NSError * _Nullable error) {
if (!success) {
// start the sdk again when it fails (network issue, etc.)
}
}];
PXPolicy *policy = [[PXPolicy alloc] init];
// configure the policy instacne
[PerimeterX setPolicyWithPolicy:policy forAppId:nil completion:nil];
How to include SDK’s headers in your URL requests
SDK's headers must be included in your URL requests. To your delight, the SDK is automatically intercepts URL requests from your app which based on URL Session (including Alamofire). By doing so, the SDK takes care of adding those headers to your URL requests, which means you don't have to do anything else.
However, you may choose to include those headers by yourself. To do so, please follow those steps:
-
You can disable requests interception by setting the
PXPolicy/requestsInterceptedAutomaticallyEnabled
to false. You must set this before calling thePerimeterX/start(appId:delegate:enableDoctorCheck:completion:)
function.PXPolicy.requestsInterceptedAutomaticallyEnabled = false // call the start function...
PXPolicy.requestsInterceptedAutomaticallyEnabled = NO; // call the start function...
-
In the policy instance, set the
PXPolicy/requestsInterceptedAutomaticallyEnabled
tofalse
:policy.requestsInterceptedAutomaticallyEnabled = false
policy.requestsInterceptedAutomaticallyEnabled = NO;
-
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) // add those headers to your URL request
NSDictionary<NSString *, NSString *> *headers = [PerimeterX headersForURLRequestForAppId:nil]; // add those headers to your URL request
Don't cache headers!
You should not cache those headers. Those headers contain a token with expiration data. The SDK manages this token to be up-to-date.
How to handle the block response from the server
To your delight, the SDK is automatically intercepts URL requests from your app which based on URL Session (including Alamofire). By doing so, the SDK takes care of handling the block response from your server, which means you don't have to do anything else.
You can verify the error object that was received with those APIs:
PerimeterX/isRequestBlockedError(error:)
- the request was blocked; Called immediately when the response from the server reach the device.PerimeterX/isChallengeSolvedError(error:)
- the request was blocked and the user solved the challenge; Called after the user solved the challenge.PerimeterX/isChallengeCancelledError(error:)
- the request was blocked and the user cancelled the challenge; Called after the user cancelled the challenge.
If you are using Alamofire, you should pass the AFError.underlyingError object to those functions. Here is an example:
if let error = response.error?.underlyingError {
let isRequestBlockedError = PerimeterX.isRequestBlockedError(error: error)
if isRequestBlockedError {
print("request was blocked by PX")
}
}
However, if you choose to include headers from the SDK to your URL request manually, you have to provide the SDK with the response as well:
After receiving an error in the response, pass the information to SDK:
let isHandledByPX = PerimeterX.handleResponse(forAppId: nil, data: data, response: response)
BOOL isHandledByPX = [PerimeterX handleResponseForAppId:nil data:data response:response];
Hybrid App support
The hybrid App uses both native URL requests and web views to communicate with the server. In the context of HUMAN, 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 the SDK achieve that, you should set your domain in the policy for the relevant AppID. Here is an example:
policy.domains.insert("my-domain.com")
policy.domains = [NSSet setWithObject:@"my-domain.com"];
If your app using Apple Pay on the Web you should disable JavaScript evaluation by the SDK. In order to protect the security of Apple Pay transactions in WKWebView, Apple Pay cannot be used alongside of script injection APIs. You can do this by setting the policy. Here is an example:
policy.allowJavaScriptEvaluation = false
policy.allowJavaScriptEvaluation = NO;
You can turn off the hybrid app support by setting the PXPolicy/hybridAppSupportEnabled
to false
. You must set this before calling the PerimeterX/start(appId:delegate:enableDoctorCheck:completion:)
function.
PXPolicy.hybridAppSupportEnabled = false
// call the start function...
PXPolicy.hybridAppSupportEnabled = NO;
// call the start function...
Enable support for Account Defender
In order to enable Account Defender, a user ID must be set. You can set it by calling the PerimeterX/setUserId(userId:forAppId:)
function with a non nil
value. When the current user logout, you should call this function again with nil
. This will turn off the Account Defender.
PerimeterX.setUserId(userId: "<the current user ID>", forAppId: nil)
[PerimeterX setUserIdWithUserId:@"<the current user ID>" forAppId:nil];
In order to tell Account Defender about the user's flow, you should call this function for each URL request that been send to your server. Notice that when the PXPolicy/requestsInterceptedAutomaticallyEnabled
is set to true
, the SDK registers URL requests automatically and you don't need to call this function.
PerimeterX.registerOutgoingUrlRequest(url: "<URL>", forAppId: nil)
[PerimeterX registerOutgoingUrlRequestWithUrl:@"<URL>" forAppId:nil];
Understanding how the SDK works
What happens when you start the SDK
The PerimeterX/start(appId:delegate:enableDoctorCheck:completion:)
function sets up the session for a given AppID. Without setting up the session, most APIs in the SDK won't work (for example, set policy or get headers). Notice that you don't need to wait until the completion handler is called in order to call other APIs. When the process ends successfully, the completion handler is called with success
as true
. However, this process can fail due to network issue. In this case, you should call the function again (we recommend waiting one second before calling it again).
When you call the PerimeterX/start(appId:delegate:enableDoctorCheck:completion:)
function, the SDK is creating a background thread to perform its work. You don't need to worry about any performance issue when calling it from the main thread.
While this function is working in the background, the SDK will still provide the required headers. It's essential to call this function as early as possible in your application and before any URL request to your server.
What is included in the SDK's headers
The headers includes a token that allow your server to verify that the URL request comes from your app, which running the SDK. The SDK receives this token from HUMAN's backend when you call the PerimeterX/start(appId:delegate:enableDoctorCheck:completion:)
function. Every few minutes the SDK communicates with HUMAN's backend to get a new token.
However, you don't need to verify that the token is exists in the headers. For example, when sending a request while the SDK is starting, the SDK's header will have an indication that the token is not available yet. This case is relevant for the first time you app launches on a device, because the token is saved persistently in the SDK and will used in the next app launch.
How the SDK presents the block page to the user
When the SDK receives the block response from the server it performs the following actions:
- Presenting a
block view controller
in the app, over your other controllers. - In the
block view controller
the SDK presents a web view which loads the challenge that must be solved by the user (or the bot). - Once the challenge is solved, the SDK removes the
block view controller
and allow the user to continue working in your app.
Next steps
Review the following topics:
- Integration verification and testing
- Callbacks from the SDK
- Handle block responses from the server
- React Native support
- Multiple AppIDs support
- Migrating from earlier SDK versions
Updated 12 days ago