> For the complete documentation index, see [llms.txt](https://docs.griaule.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.griaule.com/sdks/en/bcc-face/bccmobilefaceios.md).

# iOS

**BCC Face** is a library intended to be integrated into an iOS application from a `.framework` file.

It uses the device camera to take a photo of a face for biometric purposes. It provides a simple active liveness test, requiring the person to smile for about one second and/or look to the right or left. The liveness test includes an option to speak the instructions, making the workflow easier for users. In addition, it provides a passive liveness test that can be used to verify that the photo was taken of a real person without requiring user interaction.

This manual is up to date for BCC Face Mobile iOS version `4.12.2`.

{% hint style="warning" %}
The **passive liveness test** is only available from version `4.4.0` onwards.
{% endhint %}

### Requirements

* Git
* CocoaPods, available at <https://cocoapods.org/>.

### Installation

#### Installing Dependencies

1 - Add the following Pods to the application's dependencies in the Podfile:

```ruby
pod 'lottie-ios'
```

{% hint style="info" %}
If the application does not have a Podfile, it can be created in the root folder of your Xcode project using the `pod init` command in the terminal. The Podfile will not appear directly in Xcode; it will be created in the project directory.
{% endhint %}

Using dynamic frameworks is preferred. This can be indicated using the `use_frameworks!` flag in the Podfile.

An example Podfile with a target named **BCCs-Sample** is shown below:

```ruby
platform :ios, '15.5'

target 'BCCs-Sample' do
	use_frameworks!

	pod 'lottie-ios'
end

post_install do |installer|
	installer.pods_project.targets.each do |target|
		target.build_configurations.each do |config|
			config.build_settings['DEVELOPMENT_TEAM'] = "YOUR_DEVELOPMENT_TEAM_KEY"
			config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
		end
	end
end
```

{% hint style="warning" %}
In previous versions of BCC Face Lib iOS, it was also necessary to declare `pod 'GoogleMLKit/FaceDetection'` in the application's Podfile. As of **version 4.12.2**, if the application has this dependency, **it is recommended to remove it** and run `pod install` again. BCC Face Lib already includes MLKit internally; keeping this pod declaration will cause duplicate class warnings that may lead to instability at app startup.
{% endhint %}

{% hint style="warning" %}
It is recommended to use the same minimum iOS version for your application as the one supported by this framework: iOS 15.5, as in the example above. It is also advisable to set the `BUILD_LIBRARY_FOR_DISTRIBUTION = YES` flag in the Podfile to ensure compatibility with older SDK versions.
{% endhint %}

2 - Close the Xcode project, open a terminal, go to the folder where the Podfile is located, and then run:

```bash
pod install
```

After the execution finishes, a file with the `.xcworkspace` extension will be created in the same folder.

3 - Open the new `.xcworkspace` file.

{% hint style="warning" %}
From now on, every time the user wants to open the project, it must be opened through this `.xcworkspace` file, as it includes the dependencies.
{% endhint %}

#### Importing and Configuring

**Importing the Project**

* Open the project using the `.xcworkspace` file.
* Add the `BCCFace.framework` file to the project, then add it to your application's list of frameworks.
  * Move the `.framework` file to the project's file tree.
  * If there is already a frameworks folder, it is recommended to move the file there.
  * Open the project settings.
  * Go to the *General tab*.
  * Click and drag the `.framework` from the project tree to the `Frameworks, Libraries and Embedded Content` section.
* Change the `BCCFace.framework` setting from `Do not embed` to `Embed & Sign`.
* Change your project's target version to a minimum of iOS 15.5.

{% hint style="info" %}
It is recommended to disable iPad as a target.
{% endhint %}

**Initial Configuration**

This version has no Firebase dependencies, nor does it require an initial configuration called from the AppDelegate. The only initial configuration required is that the application must request permission to use the camera. To do so, add the following key to the `info.plist` file, in the Information Property List:

```properties
Key   :  Privacy - Camera Usage Description
Value :  Allow camera access
```

The key's value is a message shown to the user when camera usage permission is requested. This value can be left blank or filled with a custom message.

### Usage

#### Parameters and Constructor

To use the BCC Face library correctly, there are some mandatory parameters.

A simple example of using the library is shown below:

```swift
BCCFaceBuilder(self, delegate: self).initializeCapture()
```

***

The `BCCFaceBuilder` class constructor receives the following parameters:

* `hostVC: UIViewController` - View controller that calls the capture screen.
* `delegate: BCCFaceDelegate` - Interface responsible for notifying capture events (for example, failure or success).

***

The `initializeCapture` method also accepts an optional parameter, as shown below:

```swift
public func initializeCapture(
	_ navController: UINavigationController? = nil
) {
	// ...
}
```

If you want navigation to happen through a navigation controller, you must provide it when calling the method.

***

`BCCFaceBuilder` is the class responsible for handling the usage configuration of `BCCFace`. The following parameters are accepted to configure the biometric capture and the software behavior:

* `buildSmileCheck(with smileProbability: ClosedRange<Float> = 0.5...1.0)` - Adds the smile to the liveness test and sets the acceptance threshold. This feature is enabled by default.
* `removeSmileCheck()` - Removes the smile from the liveness test.
* `buildRotationCheck(_ rotationChecks: [HeadRotationCheck], headRotationAngle: ClosedRange<Float> = -6.0...6.0)` - Defines a list of head rotation liveness tests and the maximum rotation angle. This feature is enabled by default. The head rotation options are:

```swift
  enum class HeadRotationCheck {
  	case randomRotation
  	case leftRotation
  	case rightRotation
  }
```

* `removeHeadRotation()` - Removes head rotation from the liveness test.
* `addPassiveLiveness()` - Adds the passive liveness test. This feature is used to verify that the captured photo is of a real person without requiring any user interaction. To use this feature, you MUST disable the active liveness checks (`removeSmileCheck()` and `removeHeadRotation()`), which are added by default.
* `buildSpeechSettings(_ speechSettings: SpeechSettings)` - Defines the criteria for accessibility speech, using the following parameters:

```swift
  class SpeechSettings(
  	public let volume: Float
  	public let startsMuted: Bool
  	public let pitch: Float
  	public let speed: Float
  )
```

* `volume` - The audio volume between `0.0` and `1.0`.
* `startsMuted` - Defines whether the instructions start muted or not (`true` for muted).
* `pitch` - Defines the voice pitch for the instructions between `0.5` (low) and `2.0` (high).
* `speed` - Defines the voice speed for the instructions. This value must be positive.

The preset values can be accessed through the static variable:

```swift
  public static let defaultSpeechSettings = SpeechSettings(
  	volume: 1.0,
  	startsMuted: true,
  	pitch: 1.0,
  	speed: 0.5
  )
```

* `removeSpeech()` - Removes accessibility speech.
* `setInstructionEnable(_ enable: Bool)` - Defines whether the instructions screen is enabled or disabled.
* `forceLanguage(_ language: BCCLanguages?)` - Forces the instructions to be shown in a single language. If the device language is not supported, English will be used. The supported languages are:

```swift
  public enum BCCLanguages: String {
  	case ptBR = "pt-BR"
  	case enUS = "en"
  	case esMX = "es"
  	case deviceLanguage = "deviceLanguage"
  }
```

* `enableFlashButton(_ enable: Bool)` - Enables (`true`) or disables (`false`) the flash button on the rear camera. Default: disabled (`false`).
* `enableManualCapture(_ enable: Bool)` - Enables (`true`) or disables (`false`) the manual capture button, which allows bypassing the automatic capture checks. When performing a manual capture, the user will be able to review the captured photo before finishing the process.
* `setImageCompressionFormat(_ format: ImageCompressionFormat)` - Defines the compression format of a passive liveness capture. You can choose between `.jpeg` (default) or `.jpeg2000`.
* `enableIntegrityValidation(clientSecret: Data, nonce: Data)` - Enables integrity validation for passive liveness, an extra layer of security to ensure the integrity of the payload.

For reference, here is a complete list of parameters and default values:

```swift
var headRotationAngle: ClosedRange<Float> = -6.0...6.0
var openEyesProbability: ClosedRange<Float> = 0.8...1.1  // Deprecated as of 4.12.2
var smileProbability: ClosedRange<Float> = 0.5...1.0
var livenessChecks: [LivenessChecks] = [.smileDetection]
var headRotationChecks: [HeadRotationCheck] = [.randomRotation]
var speechSettings: SpeechSettings? = .defaultSpeechSettings
var cameraSettings: CameraSettings = .defaultCameraSettings
var canEnableManualCapture: Bool = false
var canEnableFlash: Bool = true
var language: BCCLanguages? = nil
var showInstructions: Bool = false
var imageCompressionFormat: ImageCompressionFormat = .jpeg
var integrityValidationData: IntegrityValidationData? = nil
```

{% hint style="warning" %}
The active liveness test (using smile and random head rotation) is enabled by default. To use only the passive liveness check, before adding it, you must remove the active liveness methods from the builder:

```swift
BCCFaceBuilder(self, delegate: self)
	.removeSmileCheck()
	.removeHeadRotation()
	.addPassiveLiveness()
```

{% endhint %}

Here is a code snippet to initialize a capture using only the passive liveness test:

```swift
// From the desired ViewController...

// Create the builder
let faceBuilder = BCCFaceBuilder(self, delegate: self)

// Configure the builder
faceBuilder
	.removeSmileCheck()
	.removeHeadRotation()
	.addPassiveLiveness()

// Initialize the capture from the builder
faceBuilder.initializeCapture(self.navigationController)
```

#### Return Values

The results of the last face capture can be retrieved using the `faceCaptureDidFinish` method of the `BCCFaceDelegate` interface:

```swift
func faceCaptureDidFinish(
	data: BCCFaceReturnData,
	analytics: BCCFaceReturnAnalytics
)
```

The `data` object contains the images captured during the process:

```swift
public struct BCCFaceReturnData {
	// Previously 'photo', renamed to follow the same pattern as Android
	public internal(set) var originalPhoto: UIImage
	public internal(set) var croppedPhoto: UIImage?

	// Passive Liveness Result
	public internal(set) var passiveResult: Data?

	// LEGACY API: same as 'originalPhoto'
	public var photo: UIImage { self.originalPhoto }
}
```

The returned properties are:

* `originalPhoto` (*image*) - The original photo taken by the camera.
* `croppedPhoto` (*image*) - The cropped photo, which is the face image cropped from the original photo.
* `passiveResult` (*Data*) - File content of the passive liveness collection. It is only present if captured successfully. It is the return of the passive liveness collection as *JPEG Data* or *JPEG 2000*. This data can be saved/exported directly to a file or sent over the network (for network transmission, the data can easily be encoded, e.g., as a Base64 string).

If the user aborts the capture or if any failure occurs during the process, the `faceCaptureDidAbort` method will be called. You can implement this method to handle this scenario.

#### Sample Project

This is a working sample project for face capture using BCC Mobile Face iOS:

```swift
import UIKit
import BCCFace

class ViewController: UIViewController {
	override func viewDidLoad() {
		super.viewDidLoad()
	}

	@IBAction func startCapture(_ sender: UIButton) {
		BCCFaceBuilder(self, delegate: self)
			.removeSmileCheck()
			.removeHeadRotation()
			.addPassiveLiveness()
			.buildCameraSettings(.frontSwitchable)
			.enableFlashButton(true)
			.initializeCapture(navigationController)
	}
}

extension ViewController: BCCFaceDelegate {
	func faceCaptureDidFinish(
		data: BCCFace.BCCFaceReturnData,
		analytics: BCCFace.BCCFaceAnalytics
	) {
		// ...
	}

	func faceCaptureDidAbort(
		analytics: BCCFace.BCCFaceAnalytics
	) {
		// ...
	}
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.griaule.com/sdks/en/bcc-face/bccmobilefaceios.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
