# Getting Started

## Getting Started with VGS Collect iOS SDK

Before you start, you can check the [`VGSCollectSDK` GitHub Page](https://github.com/verygoodsecurity/vgs-collect-ios), download the [Demo Application](https://github.com/verygoodsecurity/vgs-collect-ios/tree/master/demoapp), or browse the [SDK Reference](https://verygoodsecurity.github.io/vgs-collect-ios/index.html).

## How to Integrate the SDK

### Quickstart from Dashboard

Ensure your organization is registered at [VGS Dashboard](https://dashboard.verygoodsecurity.com/dashboard/). A Sandbox Vault will be pre-created for you. Use your [VGS Dashboard](https://dashboard.verygoodsecurity.com/dashboard/) to start collecting data. If you haven't registered an organization yet, check the [Quick Integration](/vault/vault.md#live-vaults) guides. Then, follow the VGSCollectSDK integration guide below.

### Integrate VGSCollectSDK into Your iOS Project

#### Step 1: Install the SDK

VGSCollectSDK is distributed through [Swift Package Manager](https://www.swift.org/package-manager) and [CocoaPods](https://cocoapods.org). Additionally, an **XCFramework** (distributed as `VGSCollectSDK.xcframework.zip`) is available via GitHub [releases](https://github.com/verygoodsecurity/vgs-collect-ios/releases).

#### Integrate with Swift Package Manager

To use Swift Package Manager, add the dependency `https://github.com/verygoodsecurity/vgs-collect-ios.git` in Xcode and choose the exact version. Then, select `VGSCollectSDK` and, optionally, other packages provided with `VGSCollectSDK`.\
Follow the official Apple SPM guide [instructions](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) for more details.

#### AI Agent Integration & Assisted Development

To accelerate your integration and ensure your implementation follows VGS best practices, you can use the [AGENTS.md](https://github.com/verygoodsecurity/vgs-collect-ios/blob/master/AGENTS.md) file as a context for AI Coding Agents.\
Attach or reference the URL to the AGENTS.md file to your agent's context: <https://github.com/verygoodsecurity/vgs-collect-ios/blob/master/AGENTS.md>.

**Example System Prompt:**\
"You are an autonomous engineering agent integrating the VGS Collect iOS SDK into an existing Swift app. Use the contents of AGENTS.md as your authoritative policy.\
**Goals:**

1. Add a secure card form (Number, Name, Expiration, CVC).
2. Validate all fields before submission.
3. Provide unit tests for valid/invalid card inputs.”

#### Integrate with CocoaPods

Install the latest version of [CocoaPods](https://cocoapods.org). Open Terminal and run the command:

```bash
sudo gem install cocoapods
```

If you don't have an existing `Podfile` in your project, navigate to your project folder and run the following command to create one:

```bash
pod init
```

Then, open the file in Xcode for editing:

```bash
open -a Xcode Podfile
```

Add the `VGSCollectSDK` pod to your `Podfile` inside your project folder:

```ruby
target 'MyApp' do
  use_frameworks!

  # Add VGSCollectSDK pod here
  pod 'VGSCollectSDK'

end
```

Return to your Terminal window and run the following command to install `VGSCollectSDK`:

```bash
pod install
```

From now on, open your project in Xcode using the `<your-app>.xcworkspace` file instead of the `.xcodeproj` file.

**Update Pods (Optional)**

If you previously installed `VGSCollectSDK`, you might need to update the SDK to the latest version. To do so, run the following command in Terminal:

```bash
pod update
```

#### Integrate with XCFramework

**XCFramework** integration is a separate integration method. An **XCFramework** is attached to each GitHub [release](https://github.com/verygoodsecurity/vgs-collect-ios/releases) as `VGSCollectSDK.xcframework.zip`. Only the Core SDK module is supported in the **XCFramework** distribution. To validate the **XCFramework** checksum, run in Terminal `shasum -a 256 VGSCollectSDK.xcframework.zip` and compare it with the value provided in the [VGSCollectSDK-checksum.txt](https://github.com/verygoodsecurity/vgs-collect-ios/blob/master/VGSCollectSDK-checksum.txt) file in the repository.

**Next**

Follow the integration guide to see an example of how to create a simple form for collecting credit card data and sending it to your Vault.

### Step 2: Configure Your App

Import the `VGSCollectSDK` framework and initialize a `VGSCollect` instance in your app. When initializing `VGSCollect`, set your [Vault id](/vault/vault.md) and [Environment](/vault/developer-tools/vault-management/going-live.md#sandbox-vs-live) type:

```swift
import UIKit
import VGSCollectSDK

class ViewController: UIViewController {

  /// Initialize VGSCollect instance
  var vgsCollect = VGSCollect(id: "<VAULT_ID>", environment: <ENVIRONMENT>)

  // ...
}
```

> * You can have multiple `VGSCollect` instances; each will work independently with its own configured fields.\
>   \- All `VGSCollect` instances can be configured differently.\\

The integration process consists of two steps: configuring VGS Collect UI components and sending data to VGS.

### Configure UI Components

#### Create UI Form

Add VGS Collect UI components to your view and set up the layout. More information about VGS Collect UI components is described [here](/vault/developer-tools/vgs-collect/ios-sdk/ui-components.md).

```swift
import UIKit
import VGSCollectSDK

class ViewController: UIViewController {

    /// Initialize VGSCollect instance
    var vgsCollect = VGSCollect(id: "<VAULT_ID>", environment: <ENVIRONMENT>)

    /// VGS UI components
    var cardNumberField = VGSCardTextField()
    var cardHolderNameField = VGSTextField()
    var expCardDateField = VGSTextField()
    var cvcField = VGSTextField()

    /// Native UI components
    lazy var sendButton: UIButton = {
      let button = UIButton()
      button.layer.cornerRadius = 4
      button.backgroundColor = .systemBlue
      button.setTitle("Send", for: .normal)
      button.addTarget(self, action: #selector(sendData), for: .touchDown)
      return button
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        setupLayout()
        setupFieldsConfiguration()
    }

    /// Create a UI form for collecting credit card data
    func setupLayout() {
        let stackView = UIStackView(arrangedSubviews: [cardHolderNameField, cardNumberField, expCardDateField, cvcField, sendButton])
        stackView.axis = .vertical
        stackView.spacing = 8
        stackView.distribution = .fillEqually
        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.leftAnchor.constraint(equalToSystemSpacingAfter: view.leftAnchor, multiplier: 2),
            view.rightAnchor.constraint(equalToSystemSpacingAfter: stackView.rightAnchor, multiplier: 2),
            stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 120),
            stackView.heightAnchor.constraint(equalToConstant: 250)
        ])
    }

    func setupFieldsConfiguration() {}

    @objc
    func sendData() {}
}
```

#### Setup VGS Collect Fields

Each `VGSTextField` should be configured with `VGSConfiguration`. For more details on field configuration, see [here](/vault/developer-tools/vgs-collect/ios-sdk/configuration.md).

```swift
//...

func setupFieldsConfiguration() {

    /// Create card number field configuration
    let cardConfiguration = VGSConfiguration(collector: vgsCollect, fieldName: "card_number")
    cardConfiguration.type = .cardNumber
    cardConfiguration.isRequiredValidOnly = true

    /// Set up configuration for the card number field
    cardNumberField.configuration = cardConfiguration
    cardNumberField.placeholder = "Card Number"

    /// Configure card holder name field
    let nameConfiguration = VGSConfiguration(collector: vgsCollect, fieldName: "card_cardHolderName")
    nameConfiguration.type = .cardHolderName
    cardHolderNameField.configuration = nameConfiguration
    cardHolderNameField.placeholder = "CardHolder Name"

    /// Configure card expiration date field
    let expDateConfiguration = VGSConfiguration(collector: vgsCollect, fieldName: "card_expirationDate")
    expDateConfiguration.type = .expDate
    expCardDateField.configuration = expDateConfiguration
    expCardDateField.placeholder = "Exp Date"

    /// Configure card CVC field
    let cvcConfiguration = VGSConfiguration(collector: vgsCollect, fieldName: "card_cvc")
    cvcConfiguration.type = .cvc
    cvcField.configuration = cvcConfiguration
    cvcField.placeholder = "CVC"
    cvcField.isSecureTextEntry = true

    vgsCollect.textFields.forEach { textField in
      textField.font = UIFont.systemFont(ofSize: 22)
      textField.padding = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
      textField.textColor = .darkGray
      textField.textAlignment = .natural
      textField.tintColor = .lightGray
    }
}

// ...
```

#### Observe VGSTextField States

You can observe the state of `VGSTextField` during user interactions. Read more about observing states [here](/vault/developer-tools/vgs-collect/ios-sdk/state.md).

```swift
//...
override func viewDidLoad() {
    super.viewDidLoad()

    setupLayout()
    setupFieldsConfiguration()

    /// Observing text fields
    vgsCollect.observeStates = { textFields in
        textFields.forEach { textField in
            print(textField.state.description)

            /// VGSCardState - extended state for VGSCardTextField
            if let cardState = textField.state as? VGSCardState {
                print(cardState.cardBrand.stringValue)
            }
        }
    }
}
//...
```

### Securely Collecting and Sending Information

Use `vgsCollect.sendData(_:)` to collect data from VGS Collect UI components and securely send it to your Vault. More details on sending data to your Vault can be found [here](/vault/developer-tools/vgs-collect/ios-sdk/submit-data.md).

```swift
// ...
@objc
func sendData() {

    /// Check if text fields are valid
    vgsCollect.textFields.forEach { textField in
        textField.borderColor = textField.state.isValid ? .lightGray : .red
    }

    /// Additional information will be sent along with all sensitive data from VGSCollect fields
    var extraData = [String: Any]()
    extraData["customKey"] = "Custom Value"

    vgsCollect.sendData(path: "/post", extraData: extraData) { response in
        switch response {
          case .success(_, let data, _):
            if let data = data, let jsonData = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
              print(String(data: try! JSONSerialization.data(withJSONObject: jsonData["json"]!, options: .prettyPrinted), encoding: .utf8)!)
            }
            return
          case .failure(let code, _, _, let error):
            switch code {
            case 400..<499:
               // Wrong request. This can also happen when your routes are not set up yet or your <VAULT_ID> is incorrect
               print("Wrong Request Error: \(code)")
            case VGSErrorType.inputDataIsNotValid.rawValue:
              if let error = error as? VGSError {
                print("Input data is not valid. Details:\n \(error)")
              }
            default:
              print("Something went wrong. Code: \(code)")
            }
          return
        }
    }
}
```

#### Next Steps

* [UI Components](/vault/developer-tools/vgs-collect/ios-sdk/ui-components.md)
* [Configure Text Fields with VGSConfiguration](/vault/developer-tools/vgs-collect/ios-sdk/configuration.md)
* [Configure Text Fields for Tokenization](/vault/developer-tools/vgs-collect/ios-sdk/tokenization-configuration.md)
* [Collect and Send Data](/vault/developer-tools/vgs-collect/ios-sdk/submit-data.md)
* [Samples](/vault/developer-tools/vgs-collect/ios-sdk/samples.md)


---

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