Swiftpack.co - Package - verygoodsecurity/vgs-collect-ios

CircleCI UT license Platform swift Cocoapods Compatible

VGS Collect iOS SDK

VGS Collect - is a product suite that allows customers to collect information securely without possession of it. VGSCollect iOS SDK allows you to securely collect data from your users via forms without having to have that data pass through your systems. The form fields behave like traditional input fields while securing access to the unsecured data.

Table of contents

VGS Collect iOS SDK State VGS Collect iOS SDK Response

Before you start

You should have your organization registered at VGS Dashboard. Sandbox vault will be pre-created for you. You should use your <vaultId> to start collecting data. Follow integration guide below.


VGSCollectSDK is available through CocoaPods and Carthage.


CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate VGSCollectSDK into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'VGSCollectSDK'


VGCollectSDK is also available through Carthage. Add the following line to your Cartfile:

github "verygoodsecurity/vgs-collect-ios"

then run:

carthage update --platform iOS

Note that VGSCollectSDK includes CardIO as dependency for scanning card numbers. You should also link it to your project. Follow the Carthage instructions


Import SDK into your file

import VGSCollectSDK

Create VGSCollect instance and VGS UI Elements

Use your <vaultId> to initialize VGSCollect instance. You can get it in your organisation dashboard.

Code example

Here's an example In Action
Customize VGSTextFields...
/// Initialize VGSCollect instance
var vgsCollect = VGSCollect(id: "vauiltId", environment: .sandbox)

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

/// Native UI Elements
@IBOutlet weak var stackView: UIStackView!

override func viewDidLoad() {

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

    /// Setup configuration to card number field
    cardNumberField.configuration = cardConfiguration
    cardNumberField.placeholder = "Card Number"

    /// Setup next textfields...
... observe filed states
override func viewDidLoad() {
    /// Observing text fields
    vgsCollect.observeStates = { textFields in

        textFields.forEach({ textField in
            if textdField.state.isValid {
                textField.borderColor = .grey
            } else {
                textField.borderColor = .red

            /// CardState is available for VGSCardTextField
            if let cardState = textField.state as? CardState {
... send data to your Vault
// ...

// MARK: - Send data    
func sendData() {

    /// handle fields validation before send data
    guard cardNumberField.state.isValid else {
	print("cardNumberField input is not valid")

    /// extra information will be sent together with all sensitive card information
    var extraData = [String: Any](https://raw.github.com/verygoodsecurity/vgs-collect-ios/blob/master/)
    extraData["customKey"] = "Custom Value"

    /// send data to your Vault
    vgsCollect.sendData(path: "/post", extraData: extraData) { [weak self](https://raw.github.com/verygoodsecurity/vgs-collect-ios/blob/master/response) in
      switch response {
        case .success(let code, let data, let response):
          // parse data
        case .failure(let code, let data, let response, let error):
          // handle failed request
          switch code {
            // handle error codes

VGSCardTextField automatically detects card provider and display card brand icon in the input field.

Scan Credit Card Data

VGSCollect provide secure card.io integration for collecting and setting scanned data into VGSTextFields. To use card.io with VGSCollectSDK you should add CardIO module alongside with core VGSCollectSDK module into your App Podfile:

pod 'VGSCollectSDK'
pod 'VGSCollectSDK/CardIO'

Code Example

Here's an example In Action
Setup VGSCardIOScanController...
class ViewController: UIViewController {
    var vgsCollect = VGSCollect(id: "vauiltId", environment: .sandbox)

    /// Init VGSCardIOScanController
    var scanController = VGSCardIOScanController()

    /// Init VGSTextFields...

    override func viewDidLoad() {

        /// set VGSCardIOScanDelegate
        canController.delegate = self

    /// Present scan controller 
    func scanData() {
        scanController.presentCardScanner(on: self,
				animated: true,
			      completion: nil)

    // MARK: - Send data  
    func sendData() {
        /// Send data from VGSTextFields to your Vault
... handle VGSCardIOScanControllerDelegate
// ...

/// Implement VGSCardIOScanControllerDelegate methods
extension ViewController: VGSCardIOScanControllerDelegate {

    ///Asks VGSTextField where scanned data with type need to be set.
    func textFieldForScannedData(type: CradIODataType) -> VGSTextField? {
	switch type {
	case .expirationDate:
	    return expCardDateField
	case .cvc:
	    return cvcField
	case .cardNumber:
	    return cardNumberField
	    return nil

    /// When user press Done button on CardIO screen
    func userDidFinishScan() {
	scanController.dismissCardScanner(animated: true, completion: { [weak self] in
	    /// self?.sendData()

Handle VGSCardIOScanControllerDelegate functions. To setup scanned data into specific VGSTextField implement textFieldForScannedData: . If scanned data is valid it will be set in your VGSTextField automatically after user confirmation. Check CradIODataType to get available scand data types.

Don't forget to add NSCameraUsageDescription key and description into your App Info.plist.

Upload Files

You can add a file uploading functionality to your application with VGSFilePickerController.

Code Example

Setup VGSFilePickerController...
class FilePickerViewController: UIViewController, VGSFilePickerControllerDelegate {

  var vgsCollect = VGSCollect(id: "vailtId", environment: .sandbox)
  /// Create strong referrence of VGSFilePickerController
  var pickerController: VGSFilePickerController?

  override func viewDidLoad() {

      /// create picker configuration
      let filePickerConfig = VGSFilePickerConfiguration(collector: vgsCollect,
      							fieldName: "secret_doc",
						       fileSource: .photoLibrary)

      /// init picket controller with configuration
      pickerController = VGSFilePickerController(configuration: filePickerConfig)

      /// handle picker delegates
      pickerController?.delegate = self

  /// Present picker controller
  func presentFilePicker() {
      pickerController?.presentFilePicker(on: self, animated: true, completion: nil)
... handle VGSFilePickerControllerDelegate In Action
// ...  

// MARK: - VGSFilePickerControllerDelegate
/// Check file info, selected by user
func userDidPickFileWithInfo(_ info: VGSFileInfo) {
	let fileInfo = """
		    File info:
		    - fileExtension: \(info.fileExtension ?? "unknown")
		    - size: \(info.size)
		    - sizeUnits: \(info.sizeUnits ?? "unknown")
	pickerController?.dismissFilePicker(animated: true,
					  completion: { [weak self] in

// Handle cancel file selection
func userDidSCancelFilePicking() {
	pickerController?.dismissFilePicker(animated: true)

// Handle errors on picking the file
func filePickingFailedWithError(_ error: VGSError) {
	pickerController?.dismissFilePicker(animated: true)
... send file to your Vault
// ...

// MARK: - Send File	
/// Send file and extra data
func sendFile() {

	/// add extra data to send request	
	let extraData = ["document_holder": "Joe B"]

  /// send file to your Vault
  vgsCollect.sendFile(path: "/post", extraData: extraData) { [weak self](https://raw.github.com/verygoodsecurity/vgs-collect-ios/blob/master/response) in
    switch response {
      case .success(let code, let data, let response):
        /// remove file from VGSCollect storage
      case .failure(let code, let data, let response, let error):
        // handle failed request
        switch code {
          // handle error codes

Use vgsCollect.cleanFiles() to unassign file from associated VGSCollect instance whenever you need.

Demo Application

Demo application for collecting card data on iOS is here.


  • SDK Documentation: https://www.verygoodsecurity.com/docs/vgs-collect/ios-sdk
  • API Documentation: https://verygoodsecurity.github.io/vgs-collect-ios/


To follow VGSCollectSDK updates and changes check the releases page.


  • iOS 10+
  • Swift 5
  • 3rd party libraries:
    • CardIO(optional)


VGSCollect iOS SDK is released under the MIT license. See LICENSE for details.


Stars: 5


Used By

Total: 0


Public release 1.5.3 - 2020-06-04 09:27:43

Fixes & Updates

This release include fixes & updates of cards detection and validation regex. Fixed Visa card numbers valid range.

Public release 1.5.2 - 2020-06-02 15:23:35

What's new

  • New .ssn field type that support US Social Security Number. For this field type we also create specific SSNState that returns last4 digits for SSN number.
  • New .isSecureTextEntry attribute in VGSTextField enables to switch on/off secure input settings.
  • Now you can get array with all VGSTextFields registered in VGSCollect instance as vgsCollect.textFields
  • Fixed issue with VGSCardIOScanController.delegate when it appeared to be nil after initialization.


Now default .isSecureTextEntry value for .cvc field type is false. If you need secure entry, you can set it via VGSTextField attribute:

cvcTextField.isSecureTextEntry = true

Public release 1.5.1 - 2020-05-27 17:19:02

What's new

  • Updated VGSCardTextField - now it’s possible to set cardIconLocation and cardIconSize
  • Track VGSTextField's editing events with new vgsTextFieldDidChange(_:) delegate method
  • New attributes in VGSTextField: clearButtonMode and adjustsFontForContentSizeCategory
  • Updated DinersClub validation regex to support 16 digits cards.
  • Better RTL experience

Public release 1.5.0 - 2020-05-21 11:55:06

What's new

  • In this release we finally removed Alamofire as networking manager dependency. Now the SDK is more lightweight.
  • Added inputLength & cardBrand.cardLength attributes to the State object.


Since now Alamofire is removed, that means that vgsCollect.submit(_:) & vgsCollect.submitFile(_:) methods are deprecated and removed too. Follow the MIGRATING.md for more details.

Public release 1.4.2 - 2020-05-21 10:46:43

What's new

Two new api calls added: sendData(_:) and sendFile(_:). Request from this api calls are made with native URLSession. This will help us to remove Alamofire dependency in next versions.


We will remove Alamofire dependency in v1.5.0. This will cause that submit(_:) and submitFile(_:) api calls will be removed too. Please update your api calls to sendData(_:) and sendFile(_:) before upgrading to v1.5.0.

Public release 1.4.1 - 2020-05-07 13:27:10

Fixes & Updates

  • In last release we have renamed some files and our unit test were broken, so we miss a bug when submit(:) request can return nil. In this release we fixed unit test and bug. Don't forget to update SDK version in your app.

Public release 1.4.0 - 2020-05-05 14:53:09

What's new

  • Distribution via Carthage - now it's possible to integrate VGSCollectSDK via Carthage. Check integration guides how to do it.


We did project structure refactoring and rename some files. By the way that should not have impact on your project if you already use our SDK.

Public release 1.3.5 - 2020-04-28 13:10:00

What's new

  • Divider - new VGSConfiguration attribute. If set, this will add divider string to the input text in submit request.
  • Now we support two expiration date formats: MM/YY & MM/YYYY. Change formatPattern to "##/##" or "##/####" accordingly.


  • Now input from VGSTextField with type .expDate will be send to backed with divider / in format "MM/YY". You can change default format by setting .formatPattern and .divider in field configuration.

Public release 1.3.4 - 2020-04-14 16:29:45

Fixes & Updates

  • Fix validation state for fields with type .cardHolderName when input is not empty.
  • Update validation for fields with type .expDate. Now date is valid if it starts from current month.

Public release 1.3.3 - 2020-04-13 12:55:04

What's new

  • We add and improve tons of comments to our public API. As a result we released SDK Reference Docs which you can find at https://verygoodsecurity.github.io/vgs-collect-ios/
  • While documenting our code we did internal SDK improvements

Public release 1.3.2 - 2020-04-10 11:45:35

What's new

  • We update card brand detection and validation algorithms. Now in CardState you can detect different brands for Visa Electron vs. Visa.
  • We also add support for more card numbers with different card lengths.


  • In CardState last4 digits and bin number now available for only valid card numbers.
  • Fix card icon appearance, when textfield not active yet.

Public release 1.3.1 - 2020-04-01 08:23:30

What's new

  • Dynamic CVC validation. Now we track input card number and edit enabled CVC digits to 3 or 4, that depends on card brand.
  • More customisation fields for VGSTextField. Now you can setup attributed placeholder and keyboard appearance.


  • Now on VGSCollect.submit(_:) we will return only one VGSSDKErrorInputDataIsNotValid error key for fields that set as "isRequired" or "isRequiredValidOnly". Details about fields with error provided in error userInfo dictionary.

Public release 1.3.0 - 2020-03-17 14:29:20

What’s new:

  • We present a new cool feature: VGS File Picker! Now you can collect files and images using our SDK. It's more simpler then native iOS file pickers. As usually validation and uploading functionality is done under the hood. Try it out!

Public release 1.2.3 - 2020-03-16 08:59:22

What’s new:

  • Now you can customize JSON structure which will be send on VGS. Use dot notation for field names to create nesting.

Public release 1.2.2 - 2020-02-28 10:36:48

  • New VGSConfiguration attributes: isRequired and isRequiredValidOnly. Set as true to submit valid only data.
  • New VGSError. Now VGSCollectSDK will produced errors so you can resolve them in your app.

Public release 1.2.1 - 2020-02-21 23:14:23

Removed "json" key filter from response. Now response from server is not required to be wrapped in "json" dictionary.

Public release 1.2.0 - 2020-02-10 17:06:14

  • Integration with card.io - check VGSCollectSDK/CardIO module
  • Choose preferred camera(front/back) when integrating with card.io

Public release 1.1.5 - 2020-01-31 13:27:33

  • New card brand images, available for light and dark mode
  • Send to backend VGSTextfield input text without mask dividers
  • SDK improvements

Public release 1.1.4 - 2020-01-15 11:09:51

  • SDK stability improvements

Public release 1.1.3 - 2019-12-24 12:50:35

  • Handle VGSTextfield changes with new VGSTextFieldDelegate protocol
  • Added possibility to setup keyboard type and keyboard return button via VGSConfiguration
  • VGSTextfield now support UIResponder functions: becomeFirstRestponder/resignFirstResponder

Public release 1.1.2 - 2019-12-19 14:03:25

  • Added support for RTL
  • Keyboard type updates for predefined FieldType in VGSConfiguration
  • More fields for customization VGSTextfield

Public release 1.1.1 - 2019-12-12 12:14:23

  • New VGSCardTextField class with more UI features for collecting card numbers
  • Updated demo app with VGSCardTextField examples

1.1.0 - 2019-12-11 20:10:46

Added Card Brand icon for showing in a new UI class VGSCardTextField


Public release 1.0.0 - 2019-11-28 17:24:18

  • Possibility to collect data from VGSTextfield.
  • Pre-defined fields validation(card number, cvc, expDate).
  • Demo app, examples of fields configuration and data collecting at Vault

VGSCollectSDK pre-release - 2019-11-26 16:24:05

Possibility to collect data from VGSTextfield. Pre-defined fields validation(card number, cvc, expDate).

0.0.3 - 2019-11-25 10:04:46

0.0.2 - 2019-10-10 16:41:26

- 2019-10-08 19:51:42

Beta 09/30/2019 - 2019-09-30 19:17:11