# VGS Configuration

VGSConfiguration adds more power to your `VGSTextField`. Its' attributes are used to connect `VGSTextField` with specific `VGSCollect` instance, perform built-in validations and add additional features.

## VGS Configuration

### Declaration

```swift
class VGSConfiguration
```

### Creating a VGSConfiguration

```swift
init(collector vgs: VGSCollect, fieldName: String)
```

### VGSConfiguration attributes

| **Attribute**       | **Description**                                                                                                                                                     |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fieldName           | Identifier for Redact/Reveal operations on Inbound/Outbound routes.                                                                                                 |
| isRequired          | Mark the field should be non-empty and non-nil on `VGSCollect.sendData(_:)` request. Default is **false**.                                                          |
| isRequiredValidOnly | Mark the field should be valid on `VGSCollect.sendData(_:)`. Default is **false**.                                                                                  |
| type                | `FieldType` used to define default field validation and formatting.                                                                                                 |
| formatPattern       | Input text mask pattern. If not set, will be used default masking for each `FieldType`.                                                                             |
| divider             | Divider string replace spaces or other characters in input string based on `formatPattern`. Replacement will be done during `sendData(_:)` request.                 |
| keyboardType        | Requests that a particular keyboard type be displayed when a textfield becomes first responder. If not set, will be used default keyboardType for each `FieldType`. |
| returnKeyType       | Keyboard return key.                                                                                                                                                |
| keyboardAppearance  | Keyboard Appearance Type, default is \`\`UIKeyboardAppearance.default`.`                                                                                            |
| validationRules     | A set of rules that will be applied for input validation. If `nil`, default validation rules will be applied.                                                       |
| maxInputLength      | Limit max text input length, default is `.nil`.                                                                                                                     |

Some of VGSConfiguration attribites are used to create rules for input data validation. You can check validation results represented in a `State` object.

> • When `FieldType` is **not none**, default validation will be applied to input data.\
> • When `isRequired` set as **true**, input data is **empty** or **nil** - `VGSCollect.sendData(_:)` request will return error.\
> • When `isRequiredValidOnly` set as **true**, input data is **not valid** - `VGSCollect.sendData(_:)` request will return error.\
> • For **.expCardDate** `FieldType` default `divider` is **/** character and for **.ssn** type is **-** character. For other `FieldTypes` it's empty string.\\

### VGSConfiguration FieldType

| **FieldType**     | **Description**                                                     |
| ----------------- | ------------------------------------------------------------------- |
| `.cardNumber`     | - input field for the card number                                   |
| `.cvc`            | - input field for card security code                                |
| `.date`           | - input field for the date                                          |
| `.expDate`        | - input field for the card expiration date                          |
| `.cardHolderName` | - input field for cardHolderName                                    |
| `.ssn`            | - input field for US Social Security Number                         |
| `.none`           | - input field for any type of text input with no default validation |

You can check default validation details for each specific field type [here](https://www.verygoodsecurity.com/docs/vgs-collect/ios-sdk/error-handling).

If you didn't find specific `FieldType` for your use case, you can always configure `VGSTextField` with `VGSConfiguration.fieldType = .none`. Then assign any specific rule set to the field and use other configuration attributes.

### VGSConfiguration formatPattern

The **formatPattern** string will be applied as a mask on the user input text. It also works as input characters filter.\
This pattern can be used only for visual input format in `VGSTextField`. It doesn't have an impact on input data format when you send it to VGS. In case you need to send data with additional characters, check the `Divider` section.

| **Format** | **Description**                     |              | **Example** |           |
| ---------- | ----------------------------------- | ------------ | ----------- | --------- |
| `*`        | Letters and Digits replacement char | "UA12345vgs" | `**-***`    | "UA-123"  |
| `@`        | Any letter replacement char         | "UA12345vgs" | `@@_@@@`    | "UA\_vgs" |
| `a`        | Lowercase replacement char          | "UA12345vgs" | `aaa`       | "vgs"     |
| `A`        | Uppercase replacement char          | "UA12345vgs" | `AAA`       | "UA"      |
| `#`        | Digits replacement char             | "UA12345vgs" | `#/##/##`   | "1/23/45" |

> • You can only use **non-alphaNumeric** characters as dividers in the `formatPattern` string.\
> • The `formatPattern` will not be applied to the **.cvc** `FieldType`.\
> • For more **.date** formats check `VGSDateConfiguration`.\
> • For the **.expCardDate** `FieldType` it is only allowed to set date format as `##/##` or `##/####` (that will represent `MM/YY` or `MM/YYYY` format). Changing format to `##/####` will also require field validation rule update. In other cases, the field validation `State` will fail.\
> • For more **.expCardDate** date formats check `VGSExpDateConfiguration`.

> • When you change default field `formatPattern`, check & update default validation rules for the field if needed.\
> • Characters used for describing `formatPattern` will be ignored during input validation and **sendData(\_:)** request.

### VGSConfiguration Divider

Use the `divider` if you need to replace characters in the input text. Characters will be replaced based on `formatPattern` when data are being sent to VGS.

### Examples

```swift
// ...

/// Example 1
configuration.formatPattern = "#### #### #### ####"
configuration.divider = "-"

user input: "4111111111111111"
textfield format: "4111 1111 1111 1111"
sending format: "4111-1111-1111-1111"

/// Example 2
configuration.formatPattern = "##/##/##"
configuration.divider = ":"

user input: "122030"
textfield format: "12/20/30"
sending format: "12:20:30"

// Example 3
configuration.formatPattern = "**-***"
configuration.divider = "//"

user input: "UA123"
textfield format: "UA-123"
sending format: "UA//123"

```

> • If `formatPattern` is empty string, then `divider` will be not applied.\
> • Characters used as `divider` will be ignored during input validation.

## VGSExpDateConfiguration

`VGSExpDateConfiguration` class extends `VGSConfiguration` with more specific settings for fields with type `FieldType.expDate`.

### Declaration

```swift
class VGSExpDateConfiguration: VGSConfiguration
```

### Creating a VGSExpDateConfiguration

```swift
init(collector vgs: VGSCollect, fieldName: String)
```

### VGSExpDateConfiguration attributes

| **Attribute**    | **Description**                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------- |
| inputSource      | VGSTextFieldInputSource - date input source type, could be **.keyboard** or **.datePicker**.      |
| inputDateFormat  | VGSCardExpDateFormat - date format that user use for date input.                                  |
| outputDateFormat | VGSCardExpDateFormat - date format that will be send to your Vault.                               |
| serializers      | \[VGSFormatSerializerProtocol] - an array of serializers to format data being sent to the server. |

### VGSCardExpDateFormat available options

| **VGSCardExpDateFormat** | **Date Format** | **Input Format Pattern** |
| ------------------------ | --------------- | ------------------------ |
| `.shortYear`             | `mm/yy`         | `##/##`                  |
| `.longYear`              | `mm/yyyy`       | `##/####`                |
| `.shortYearThenMonth`    | `yy/mm`         | `##/##`                  |
| `.longYearThenMonth`     | `yyyy/mm`       | `####/##`                |

> • Changing `.inputDateFormat` could require field `VGSValidationRuleCardExpirationDate` rule updates(default validation expects `.shortYear` as field input format).\\

### Change Output Date format

You can change date format when sending data to your backend by setting `VGSExpDateConfiguration.outputDateFormat` in field configuration.

### Code example

```swift
/// Change output card expiration date format form "mm/yy" to "mm/yyyy"

/// Use `VGSExpDateConfiguration` when you need to convert output date format
let expDateConfiguration = VGSExpDateConfiguration(collector: vgsCollect, fieldName: "card_expirationDate")
expDateConfiguration.type = .expDate
expDateConfiguration.divider = "/"
expDateConfiguration.formatPattern = "##/##"

/// Set date format that user use for input
expDateConfiguration.inputDateFormat = .shortYear // "mm/yy" -> 01/25

/// Set  date format that will be send to your Vault
expDateConfiguration.outputDateFormat = .longYear // "mm/yyyy" -> 01/2025

....

/// Change output card expiration date format from "mm/yy" to "yyyy/mm"
let expDateConfiguration = VGSExpDateConfiguration(collector: vgsCollect, fieldName: "card_expirationDate")
expDateConfiguration.type = .expDate
expDateConfiguration.divider = "/"
expDateConfiguration.formatPattern = "##/##"

/// Set  date format that user use for input
expDateConfiguration.inputDateFormat = .shortYear //  "mm/yyyy" -> 01/2025

/// Set  date format that will be send to your Vault
expDateConfiguration.outputDateFormat = .longYearThenMonth // "yyyy/mm" -> 2025/01

/// Update validation rules(default validation expects .shortYear)
expDateConfiguration.validationRules = VGSValidationRuleSet(rules: [
  VGSValidationRuleCardExpirationDate(dateFormat: .shortYear, error: VGSValidationErrorType.expDate.rawValue)
])
```

> • To change output date format you should setup both **.inputDateFormat** and **outputDateFormat**.\
> • For validation, VGSCollect use input from VGSTextField.\\

### Separate Expiration Date Components

You can send expiration month and year as different fields. This could be done with `VGSExpDateSeparateSerializer`.

## Code example

```swift
/// Setup `VGSExpDateConfiguration` for you field
let expDateConfiguration = VGSExpDateConfiguration(collector: vgsCollect, fieldName: "card_expirationDate")
expDateConfiguration.type = .expDate

/// Setup VGSExpDateSeparateSerializer with specific fieldNames for month and year date components
let expDateSerializer = VGSExpDateSeparateSerializer(monthFieldName: "card_date.month", yearFieldName: "card_date.year")
expDateConfiguration.serializers = [expDateSerializer]
```

**JSON to submit:**

```json
/// The result JSON for input date 03/25 will have next structure:
"card_date" : {
  "year" : "25",
  "month" : "03"
}
```

If you need more advanced options to customise JSON structure, check our examples [here](/vault/developer-tools/vgs-collect/ios-sdk/submit-data.md#advanced-settings).

### VGSConfiguration maxInputLength

You can limit max text input length with `.maxInputLength` option.

## Code example

```swift
/// Setup
 let cityFieldConfiguration = VGSConfiguration(collector: vgsCollect, fieldName: "city")
 cityFieldConfiguration.maxInputLength = 32
```

> • Setting both `.formatPattern` and `.maxInputLength` options may cause unpredictable issues with text formatting.\\

## VGSDateConfiguration

`VGSDateConfiguration` class extends `VGSConfiguration` with more specific settings for fields with type `FieldType.date`.

### Declaration

```swift
class VGSDateConfiguration: VGSConfiguration
```

### Creating a VGSDateConfiguration

```swift
init(collector vgs: VGSCollect, fieldName: String, datePickerStartDate: VGSDate? = nil, datePickerEndDate: VGSDate? = nil)
```

> • If `datePickerStartDate` or `datePickerEndDate` are not set, the configuration will use the default dates as:\
> `datePickerStartDate`: Today minus 100 years.\
> `datePickerEndDate`: Today plus 100 years.\
> • You should use the same `.datePickerStartDate` and `.datePickerStartDate` of the configuration in the `.start` and `.end` dates of the validation rule `VGSValidationRuleDateRange`. Using different dates could lead in unexpected results.\\

### VGSDateConfiguration attributes

| **Attribute**    | **Description**                                                                                                          |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| inputSource      | VGSTextFieldInputSource - date input source type, could be **.keyboard** or **.datePicker**. Defaults to **.datePicker** |
| inputDateFormat  | VGSDateFormat - date format that user use for date input.                                                                |
| outputDateFormat | VGSDateFormat - date format that will be send to your Vault.                                                             |
| serializers      | \[VGSFormatSerializerProtocol] - an array of serializers to format data being sent to the server.                        |

### VGSDateFormat available options

| **VGSDateFormat** | **Date Format** | **Input Format Pattern** |
| ----------------- | --------------- | ------------------------ |
| `.mmddyyyy`       | `mm-dd-yyyy`    | `##-##-####`             |
| `.ddmmyyyy`       | `dd-mm-yyyy`    | `##-##-####`             |
| `.yyyymmdd`       | `yyyy-mm-dd`    | `####-##-##`             |

> • You should use the same `.inputDateFormat` of the configuration in the `.dateFormat` of the validation rule `VGSValidationRuleDateRange`. Using different formats could lead in unexpected results.\\

### Change Output Date format

You can change date format when sending data to your backend by setting `VGSDateConfiguration.outputDateFormat` in field configuration.

### Code example

```swift
/// Change output date format from "mm/dd/yyyy" to "yyyy/mm/dd"

/// Use `VGSDateConfiguration` when you need to convert output date format
let dateConfiguration = VGSDateConfiguration(collector: vgsCollect, fieldName: "date")
dateConfiguration.type = .date
dateConfiguration.divider = "/"
dateConfiguration.formatPattern = "##/##/####"

/// Set date format that user use for input
dateConfiguration.inputDateFormat = .mmddyyyy // "mm/dd/yyyy" -> 01/02/2025

/// Set date format that will be send to your Vault
dateConfiguration.outputDateFormat = .yyyymmdd // "yyyy/mm/dd" -> 2025/01/02

/// Update validation rules, date format should be the same used in the configuration inputDateFormat
dateConfiguration.validationRules = VGSValidationRuleSet(
  rules: [
    VGSValidationRuleDateRange(
      dateFormat: .mmddyyyy,
      error: VGSValidationErrorType.date.rawValue
    )
  ]
)
```

### Change validation range dates

You can set a range to validate the input added to `VGSDateTextField`. You can set the start date, end date or none of them. To set the range, use the `VGSDateConfiguration` constructor to pass the `datePickerStartDate` and `datePickerEndDate`. Also, you need to add a validation rule `VGSValidationRuleDateRange` using exactly the same `start` and `end` dates.

### Code example

```swift

/// Define range validation
/// The validation will fails if the date is before 01/01/2010 or after 01/01/2020
let startDate = VGSDate(day: 1, month: 1, year: 2010)
let endDate = VGSDate(day: 1, month: 1, year: 2020)

/// Use `VGSDateConfiguration` when you need to set validation date range
let dateConfiguration = VGSDateConfiguration(
  collector: vgsCollect,
  fieldName: "date",
  datePickerStartDate: startDate,
  datePickerEndDate: endDate
)

// ...

/// Update validation rules, `start` and `end` should be the same used in the configuration `datePickerStartDate` and `datePickerEndDate`
dateConfiguration.validationRules = VGSValidationRuleSet(
  rules: [
    VGSValidationRuleDateRange(
      dateFormat: .mmddyyyy,
      error: VGSValidationErrorType.date.rawValue,
      start: startDate
      end: endDate
    )
  ]
)
```

> • To change output date format you should setup both **.inputDateFormat** and **outputDateFormat**.\
> • For validation, VGSCollect use input from VGSTextField.\\

### Separate Date Components

You can send day, month and year as different fields. This could be done with `VGSDateSeparateSerializer`.

## Code example

```swift
/// Setup `VGSDateConfiguration` for you field
let dateConfiguration = VGSDateConfiguration(collector: vgsCollect, fieldName: "date")
dateConfiguration.type = .date
dateConfiguration.inputDateFormat = .ddmmyyyy

/// Setup VGSDateSeparateSerializer with specific fieldNames for day, month and year date components
let dateSerializer = VGSDateSeparateSerializer(
    dayFieldName: "date.day",
    monthFieldName: "date.month",
    yearFieldName: "date.year"
)
dateConfiguration.serializers = [dateSerializer]
```

**JSON to submit:**

```json
/// The result JSON for input date 01/03/2025 will have next structure:
"date" : {
  "day": "01",
  "month" : "03",
  "year" : "2025"
}
```


---

# 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.verygoodsecurity.com/vault/developer-tools/vgs-collect/ios-sdk/configuration.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.
