# 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.

![](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2F3Ody2xl9Cdk0ucM7MgQy%2Ffebe5bc3-b994-4f53-b583-e0988472f83d.jpg?alt=media\&token=0746bbe8-9e7c-469c-8bce-18408454ce75)

### 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="https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FEJiUC0AqR4izi0pGnfgT%2Fimage.png?alt=media&#x26;token=57d4fafa-3b76-457b-93fe-c56109cd4430" 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 %}
