# iOS

## 1. Installation

How to install Preventor iOS SDK

* [Requirements](#parte2)
* [Install via CocoaPods](#install-via-cocoapods)
* [Install via Swift Package Manager](#install-via-swift-package-manager)

### **Requirements**

The latest stable version of [Xcode](https://developer.apple.com/xcode/), since the SDK is written in Swift 5.7.1

Minimum target: iOS 13.0.

### Install via CocoaPods

To always use the latest release, add the following to your Podfile:

```objectivec
pod 'PreventorSDK'
```

Alternatively, pin to a specific version (e.g. 0.2.2):

```objectivec
pod 'PreventorSDK', '2.1.0'
```

And then [run](https://guides.cocoapods.org/using/pod-install-vs-update.html):&#x20;

```shell
pod install
```

### Install via Swift Package Manager

```swift
import PackageDescription

let package = Package(
  name: "YourTestProject",
  platforms: [
       .iOS(.v13),
  ],
  dependencies: [
    .package(name: "PreventorSDK", url: "https://github.com/preventorid/button-ios-sdk.git", from: "2.1.0)
  ],
  targets: [
    .target(name: "YourTestProject", dependencies: ["PreventorSDK"])
  ]
)
```

#### **Adding it to an existent iOS Project via Swift Package Manager**

1. Using Xcode go to File > Swift Packages > Add Package Dependency
2. Paste the project URL: <https://github.com/preventorid/button-ios-sdk.git>
3. Click on next and select the project target
4. Don't forget to set `DEAD_CODE_STRIPPING = NO` in your `Build Settings` (<https://bugs.swift.org/plugins/servlet/mobile#issue/SR-11564>)

## 2. Initialize SDK

For integration, you need to configure the pre-padding shown below. You must first implement the `PSDKConfig` structure.

### Credential prefill

```swift
self.config = PSDKConfig(flowID: "YOUR_FLOW_ID",
                         cifCode: "YOUR_CIFCODE",
                         apiKey: "YOUR_API_KEY",
                         tenant: "YOUR_TENANT",
                         env: "YOUR_ENV",
                         banknu: "YOUR_BANKNU",
                         secret: "YOUR_CLIENT_SECRET",
                         invitation: "YOUR_INVITATION_ID",
                         broker: "YOUR_BROKER")
```

{% hint style="info" %}
If the cifCode is empty or nil, a unique code is assigned.
{% endhint %}

<table><thead><tr><th>Value</th><th>Description</th><th data-hidden></th></tr></thead><tbody><tr><td>YOUR_FLOW_ID</td><td>Defines the biometric process</td><td></td></tr><tr><td>UNIQUE_CUSTOMER_CODE</td><td>Is the unique customer profile code.</td><td></td></tr><tr><td>YOUR_API_KEY</td><td>Your provided apikey.</td><td></td></tr><tr><td>YOUR_CLIENT_SECRET</td><td>Your provided clientsecret.</td><td></td></tr><tr><td>YOUR_TENANT</td><td>Your provided tenant.</td><td></td></tr><tr><td>YOUR_BANKNU</td><td>Your provided banknu.</td><td></td></tr><tr><td>YOUR_ENV</td><td>Your provided env.</td><td></td></tr><tr><td>YOUR_INVITATION_ID</td><td>Your invitation ID</td><td></td></tr><tr><td>YOUR_BROKER</td><td>Your broker</td><td></td></tr></tbody></table>

To initialize the SDK, you need to call the initialize(config: PSDKConfig) method:

```swift
self.config = PSDKConfig(flowID: "YOUR_FLOW_ID",
                         cifCode: "YOUR_CIFCODE",
                         apiKey: "YOUR_API_KEY",
                         tenant: "YOUR_TENANT",
                         env: "YOUR_ENV",
                         banknu: "YOUR_BANKNU",
                         secret: "YOUR_CLIENT_SECRET",
                         invitation: "YOUR_INVITATION_ID",
                         broker: "YOUR_BROKER")
PSDK.shared.initialize(config: config)
```

## &#x20;3. Start the Verification

To start a new verification, you first need to create the `PreventorButton`

### Add Button via Storyboard

Two simple steps to get the button running:

1. Drag a new button on your storyboard and give it your desired constraints.
2. Subclass the button as `PreventorButton`. Ensure that the module also says `PreventorSDK` below the class.

![](/files/JKhbwQhrXbdGVReClxVO)

### Add PreventorButton in your project programmatically

{% tabs %}
{% tab title="SwiftUI" %}

```swift
import SwiftUI
import PreventorSDK

struct ContentView: View {
    
    @ObservedObject var store: ContentViewModel
    let config: PSDKConfig
    
    var body: some View {
        PreventorButton()
    }
    
    init() {
        self.config = PSDKConfig(flowID: "YOUR_FLOW_ID",
                                 cifCode: "YOUR_CIFCODE",
                                 apiKey: "YOUR_API_KEY",
                                 tenant: "YOUR_TENANT",
                                 env: "YOUR_ENV",
                                 banknu: "YOUR_BANKNU",
                                 secret: "YOUR_CLIENT_SECRET",
                                 invitation: "YOUR_INVITATION_ID",
                                 broker: "YOUR_BROKER")
        PSDK.shared.initialize(config: config) { isSuccessful in
             //your code
        }
    }
}

class ContentViewModel: ObservableObject, PSDKDelegate {
    //YOUR IMPLEMENTATION
    func updatePreventorSDKDelegate() {
        PSDK.shared.delegate = self
    }

    func onStart() {
        print("onStart")
    }
    
    func onFinish(result: PSDKResult) {
        print("onFinish")
    }
    
    func onError(error: PSDKErrorCode) {
        print("error:", error.rawValue)
    }
    
    func onSubmitted(result: PSDKResult) {
        print("onSubmitted")
    }
    
}
```

{% endtab %}

{% tab title="Swift" %}

```swift
import UIKit
import PreventorSDK

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Add the button with dimensions
        let button = UIPreventorButton(frame: CGRect(x: 40, y: 90, width: 300, height: 60))
        self.view.addSubview(button)
        
        // Or Add button with autolayout support
        let button = UIPreventorButton(frame: .zero)
        button.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(button)
        let buttonConstraints = [
                button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50.0),
                button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50.0),
                button.topAnchor.constraint(lessThanOrEqualTo: self.view.topAnchor, constant: 60.0),
                button.heightAnchor.constraint(equalToConstant: 40),
        ]
        NSLayoutConstraint.activate(buttonConstraints)
        updatePreventorSDKDelegate()
    }
    
}

extension ViewController: PSDKDelegate {
    //YOUR IMPLEMENTATION
    func updatePreventorSDKDelegate() {
        PSDK.shared.delegate = self
    }

    func onStart() {
        print("onStart")
    }
    
    func onFinish(result: PSDKResult) {
        print("onFinish")
    }
    
    func onError(error: PSDKErrorCode) {
        print("error:", error.rawValue)
    }
    
    func onSubmitted(result: PSDKResult) {
        print("onSubmitted")
    }
    
}
```

{% endtab %}
{% endtabs %}

### Start Verification

To start a check, just click the PreventorButton

### Adjust Your App's Permissions

<figure><img src="/files/yZ47H9Y0heZiRFe0THyc" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you made it until here, you've successfully installed the Preventor SDK for iOS. Now let's adjust your last settings and start your first verification.
{% endhint %}

Please add the following permissions to your app's `Info.plist`, so that the Preventor iOS SDK can access a user's camera to run a verification. You can do this in the property list view or by code.

Right-click somewhere outside the table and select `Add Row`. Now add the entries like below.

Or if you prefer to do this step with code, right-click on `Info.plist` and select Open As -> Source Code. Add the lines below somewhere inside the `<dict>   </dict>`

```xml
<!-- permission strings to be include in info.plist -->
<key>NSCameraUsageDescription</key>
<string>Please give us access to your camera, to complete the verification.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Please give us access to your location to complete the verification.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Please give us access to your location to complete the verification.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Please give us access to your photo library to verify you.</string>
<key>NFCReaderUsageDescription</key>
<string>Give us NFC access to complete verification.</string>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
	<string>TAG</string>
</array>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
	<string>A0000002471001</string>
	<string>E80704007F00070302</string>
	<string>A000000167455349474E</string>
	<string>A0000002480100</string>
	<string>A0000002480200</string>
	<string>A0000002480300</string>
	<string>A00000045645444C2D3031</string>
</array>
```

{% hint style="success" %}
You have successfully finished setting up the `Preventor` iOS SDK! 🎉
{% endhint %}

### Customization

If you want to add your own customization you can use the following methods

<table><thead><tr><th>Method</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>setNavigationTitle
</code></pre></td><td>Use this method to change the navigation title of the SDK.</td></tr></tbody></table>

## 4. Handling Verifications

To find out if a user started, completed, canceled or failed the verification process, you can implement the following delegate methods:

<table><thead><tr><th>Method</th><th width="179">Description</th><th data-hidden></th></tr></thead><tbody><tr><td><code>onStart</code></td><td>This callback method is triggered once a user starts the verification flow. </td><td></td></tr><tr><td><code>onSubmitted</code></td><td>Method that is being called once verification data is submitted to Preventor.</td><td></td></tr><tr><td><code>onFinish</code></td><td>Method that is being called once a user clicks the "Finish" button.</td><td></td></tr><tr><td><code>onError</code></td><td><p>This callback method fires when a user canceled the verification flow, the verification ended with an error, or the user performed an incorrect process. You can use this to find out the reason for the error.</p><p>Error codes: </p><p><code>CANCELLED_BY_USER</code></p><p><code>BIOMETRIC_AUTHENTICATION_FAILED</code></p><p><code>BAD_STEP_BY_USER MISSING_PARAMETERS</code></p></td><td></td></tr><tr><td><code>onNextStep</code></td><td>This callback method is called when the SDK is ready to move on to the next check.</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="SwiftUI" %}

```swift
import SwiftUI
import PreventorSDK


struct ContentView: View {
    
    @ObservedObject var store: ContentViewModel
    let config: PSDKConfig
    
    var body: some View {
        PreventorButton()
    }
    
    init() {
        self.config = PSDKConfig(flowID: "YOUR_FLOW_ID",
                                 cifCode: "YOUR_CIFCODE",
                                 apiKey: "YOUR_API_KEY",
                                 tenant: "YOUR_TENANT",
                                 env: "YOUR_ENV",
                                 banknu: "YOUR_BANKNU",
                                 secret: "YOUR_CLIENT_SECRET",
                                 invitation: "YOUR_INVITATION_ID",
                                 broker: "YOUR_BROKER")
        PSDK.shared.initialize(config: config) { isSuccessful in
             //your code
        }
    }
}

class ContentViewModel: ObservableObject, PSDKDelegate {
    //YOUR IMPLEMENTATION
    func updatePreventorSDKDelegate() {
        PSDK.shared.delegate = self
    }

    func onStart() {
        print("onStart")
    }
    
    func onFinish(result: PSDKResult) {
        print("onFinish")
    }
    
    func onError(error: PSDKErrorCode) {
        print("error:", error.rawValue)
    }
    
    func onSubmitted(result: PSDKResult) {
        print("onSubmitted")
    }
    
}

```

{% endtab %}

{% tab title="Swift" %}

```swift
import UIKit
import PreventorSDK

class ViewController: UIViewController{
    
    @IBOutlet weak var PreventorButton: UIPreventorButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Add the button with dimensions
        let button = UIPreventorButton(frame: CGRect(x: 40, y: 90, width: 300, height: 60))
        self.view.addSubview(button)
        
        // Or Add button with autolayout support
        let button = UIPreventorButton(frame: .zero)
        button.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(button)
        let buttonConstraints = [
                button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50.0),
                button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50.0),
                button.topAnchor.constraint(lessThanOrEqualTo: self.view.topAnchor, constant: 60.0),
                button.heightAnchor.constraint(equalToConstant: 40),
        ]
        NSLayoutConstraint.activate(buttonConstraints)
        
        let config = PSDKConfig(flowID: "YOUR_FLOW_TYPE",
                                 cifCode: "YOUR_CIFCODE",
                                 apiKey: "YOUR_API_KEY",
                                 tenant: "YOUR_TENANT",
                                 env: "YOUR_ENV",
                                 banknu: "YOUR_BANKNU",
                                 secret: "YOUR_CLIENT_SECRET")
        updatePreventorSDKDelegate()
        PSDK.shared.initialize(config: config)
    }
    
}

extension ViewController: PSDKDelegate {
    //YOUR IMPLEMENTATION
    func updatePreventorSDKDelegate() {
        PSDK.shared.delegate = self
    }

    func onStart() {
        print("onStart")
    }
    
    func onFinish(result: PSDKResult) {
        print("onFinish")
    }
    
    func onError(error: PSDKErrorCode) {
        print("error:", error.rawValue)
    }
    
    func onSubmitted(result: PSDKResult) {
        print("onSubmitted")
    }
    
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.preventor.com/mobile-client-side-sdks/ios.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
