> This page is for Applications Protection.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.humansecurity.com/llms.txt.

# Integration with Flutter

#### v3.0

The SDK can be integrated into [Flutter](https://flutter.dev/) projects.

## Start the SDK

The automatic interceptor is not supported in Flutter, so any request from the Dart code has to be handled manually. Here is an example:

```none
do {
    let policy = PXPolicy()
    policy.urlRequestInterceptionType = .none
    try PerimeterX.start(appId: "<APP_ID>", delegate: self, policy: policy)
}
catch {
    print("error: \(error)")
}
```

## Setup a channel

Configure the channel in Dart. Here is an example:

```none
static const perimeterxPlatform = MethodChannel('com.my.app/perimeterx');
```

Setup a channel in order to handle calls from the Dart code. Here is an example:

```none
func setupChannel(with controller: FlutterViewController) {
    let perimeterxChannel = FlutterMethodChannel(name: "com.my.app/perimeterx", binaryMessenger: controller.binaryMessenger)
        perimeterxChannel.setMethodCallHandler({(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
        if call.method == "_getPxHeaders" {
            var json: String?
            do {
                if let headers = PerimeterX.headersForURLRequest() {
                    let data = try JSONSerialization.data(withJSONObject: headers)
                    json = String(data: data, encoding: .utf8)
                }
            }
            catch {
                print("error: \(error)")
            }
            result(json)
        }
        else if call.method == "_handlePxResponse" {
            if let response = call.arguments as? String, let data = response.data(using: .utf8), let httpURLResponse = HTTPURLResponse(url: URL(string: "https://fake.url.com")!, statusCode: 403, httpVersion: nil, headerFields: nil) {
                let handled = PerimeterX.handleResponse(response: httpURLResponse, data: data) { challengeResult in
                    result(challengeResult == .solved ? "solved" : "cancelled")
                }
                if handled {
                    return
                }
            }
            result("false")
        }
        else {
            result("")
        }
    })
}
```

## Pass the SDK's HTTP headers to the Dart code and handle the response

In your Dart code, call those functions for every URL request to add those HTTP headers and handle the response. Here is an example:

```none
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<void> _sendUrlRequest() async {
    try {
        final String pxHeaders = await perimeterxPlatform.invokeMethod('_getPxHeaders');
        final Map<String, String> pxHeadersMap = Map.from(json.decode(pxHeaders));
        print(pxHeadersMap);
        var url = Uri.https('my.request.com', '/my.path');
        var response = await http.get(url, headers: pxHeadersMap);
        if (response.statusCode == 403) {
            final String result = await perimeterxPlatform.invokeMethod('_handlePxResponse', response.body);
            print(result);
            /*
                check the result:
                'false' - not handled by the SDK
                'solved' - challenge solved
                'cancelled' - challenge cancelled
            */
            if (result == 'solved') {
                // challenge solved. you may retry the request here
                print("challenge solved");
            } else if (result == 'false') {
                // request finished successfully
                print("request finished successfully");
            } else if (result == 'cancelled') {
                // challenge cancelled
                print("challenge cancelled");
            }
        }
    } on PlatformException catch (e) {
        print("failed to get px's headers: '${e.message}'.");
    }
}
```