VGSCollect
@MainActor
public class VGSCollect : @MainActor VGSCardAttributesLookupService
A collector object that registers secure input fields (VGSTextField) and submits their data/files to a VGS Vault.
Summary: Provides the orchestration layer for secure data collection: field registration, state observation, JSON/body construction, vault/network submission, tokenization/alias creation and file lifecycle management.
Responsibilities:
- Registers text fields automatically when a
VGSConfigurationreferencing this collector is assigned. - Observes editing state via
observeFieldState(focused field) andobserveStates(all fields snapshot). - Submits values with
sendData/sendFile(closure, async/await, Combine variants). - Performs tokenization (
tokenizeData) and alias creation (createAliases), plus card creation via CMP (createCard). - Cleans up attached files after successful upload (
cleanFiles).
Security:
- Never logs or exposes raw sensitive values through public APIs.
- Avoid adding PII or secrets to
customHeaders&fieldNamevalues; use them strictly for routing/auth metadata. - Internal storage is transient and cleared/replaced as input changes; persistence is the caller’s responsibility (and should only store aliases).
Usage:
- Initialize with vault id & environment:
let collector = VGSCollect(id: vaultId, environment: .sandbox). - Create a
VGSConfigurationper field and assign to eachVGSTextField(registration happens automatically). - Optionally set observation closures for validation/UI updates.
- Validate all required fields (
state.isValid) before calling a submit method. - Parse response aliases/tokens; discard raw user input from UI components.
- After file submission success, call
cleanFiles().
Invariants / Preconditions:
idmust be a non-empty vault identifier.- All required fields should be valid before invoking submission APIs.
- Only one logical file should be attached when calling
sendFile. - For alias creation (
createAliases), appropriate authentication must be provided incustomHeaders. - UI access (field state collection) occurs on the main thread; ensure you invoke async calls from the main actor when updating UI.
See also:
VGSConfiguration(per-field setup)VGSCollectRequestOptions(JSON mapping policy)VGSValidationRuleSet(custom validation)
-
A dictionary of custom HTTP header key-value pairs applied to all subsequent network submissions initiated by this collector.
Purpose: Provide route-specific auth tokens (e.g. Bearer JWT), idempotency or correlation identifiers.
Security:
- Never include raw PAN/CVC/SSN or other sensitive user input.
Declaration
Swift
@MainActor public var customHeaders: [String : String]? { get set }
-
Closure invoked on every editing event for the currently focused
VGSTextField.Purpose: Supply real-time, field-specific validation feedback or UI updates (e.g. show/hide error label).
Behavior:
- Called after input changes or focus transitions.
- Provides access to
textField.statefor validation and metadata (e.g. card brand via cast toVGSCardState).
Usage:
collector.observeFieldState = { tf in if !tf.state.isValid { /* highlight */ } }Declaration
Swift
@MainActor public var observeFieldState: ((_ textField: VGSTextField) -> Void)? -
Closure invoked on every editing event with a snapshot array of all registered
VGSTextFieldinstances.Purpose: Evaluate aggregate form validity or enable/disable a submit button.
Behavior:
- Each field’s
.statereflects latest formatting & validation outcome.
Usage:
collector.observeStates = { fields in submitButton.isEnabled = fields.allSatisfy { $0.state.isValid } }Declaration
Swift
@MainActor public var observeStates: ((_ form: [VGSTextField]) -> Void)? - Each field’s
-
All text fields currently registered with this collector.
Registration: Occurs automatically when a
VGSConfigurationwhosecollectoris this instance is assigned to aVGSTextField.Usage:
let allValid = collector.textFields.allSatisfy { $0.state.isValid }Notes: Treat as read-only snapshot; use unsubscribe APIs to remove fields cleanly.
Declaration
Swift
@MainActor public var textFields: [VGSTextField] { get }
-
Creates a collector bound to a specific vault environment string.
Parameters:
- id: Non-empty vault identifier.
- environment: Environment string (e.g. “sandbox”, “live”, “live-eu1”).
- hostname: Optional custom hostname override (nil uses default vault routing).
Preconditions:
idshould be valid; empty values will lead to failing upstream requests.
Behavior:
- Initializes a collector for direct vault-based usage.
- Tracks a
CollectInitanalytics event withformType=create.
Usage:
let collector = VGSCollect(id: vaultId, environment: "sandbox")Prefer the convenience initializer for typed environment + region when possible.
Declaration
Swift
@MainActor public convenience init(id: String, environment: String, hostname: String? = nil) -
Convenience initializer composing a regional environment string.
Parameters:
- id: Vault identifier.
- environment: Enumerated environment (
.sandboxor.live). - dataRegion: Optional region segment (e.g. “eu1”) appended to environment.
- hostname: Optional custom hostname.
Usage:
let collector = VGSCollect(id: vaultId, environment: .live, dataRegion: "eu1")Declaration
Swift
@MainActor public convenience init(id: String, environment: Environment = .sandbox, dataRegion: String? = nil, hostname: String? = nil)
-
Asynchronously configures and initializes a VGSCollect instance.
This method:
- Validates the provided form name.
- Loads the Form Configuration from the backend.
- Applies remote configuration, or caller-provided inline configuration when the remote configuration is unavailable.
Behavior:
- Valid remote configuration takes precedence over inline configuration.
- A remote configuration failure is reported through
onError;completionstill receives a usable collector configured from the inline fallback when available. - Invalid form names remain terminal and are returned through
completionas failures.
Error Mapping:
- Invalid form name format returns
VGSErrorType.invalidFormConfigurationwith keyVGSSDKErrorInvalidFormConfiguration. Configuration URL, network, empty body, decoding, and non-2xx failures are delivered to
onErrorand do not prevent collector creation.
Usage:
VGSCollect.session(with: formId, vaultId: vaultId, environment: .sandbox, dataRegion: nil) { result in switch result { case .success(let collector): self.collector = collector case .failure(_, _, _, let error): self.errorText = error?.localizedDescription } }Declaration
Swift
@MainActor public static func session(with form: String, vaultId: String, environment: Environment = .sandbox, dataRegion: String? = nil, completion: @escaping (VGSCollectSessionResponse) -> Void)Parameters
formThe unique Form Name.
vaultIdVault identifier.
environmentThe environment (e.g., “sandbox”, “live”).
dataRegionOptional data region appended to the environment string.
configurationOptional inline Form Configuration
configobject used only when remote configuration cannot be loaded.onErrorOptional callback for remote configuration loading errors.
completionA closure returning
VGSCollectSessionResponse. -
Initializes a session collector with an optional inline fallback Form Configuration.
Remote configuration takes precedence. If it cannot be loaded,
onErrorreceives the load error and the collector usesconfigurationwhen supplied.Declaration
Swift
@MainActor public static func session(with form: String, vaultId: String, environment: Environment = .sandbox, dataRegion: String? = nil, configuration: [String: Any]?, onError: ((Error) -> Void)? = nil, completion: @escaping (VGSCollectSessionResponse) -> Void)
-
Returns the first registered field matching a given
fieldName.Parameter:
- fieldName: The JSON key assigned in its
VGSConfiguration.
Returns:
VGSTextField?found ornilif no match.
Usage:
if let cardField = collector.getTextField(fieldName: "card_number"), cardField.state.isValid { /* ... */ }Declaration
Swift
@MainActor public func getTextField(fieldName: String) -> VGSTextField? - fieldName: The JSON key assigned in its
-
Unregisters a single text field from this collector.
Parameter:
- textField: Field instance to detach.
Effects:
- Field is excluded from future submissions and observation callbacks.
Usage:
collector.unsubscribeTextField(nameField)Declaration
Swift
@MainActor public func unsubscribeTextField(_ textField: VGSTextField) -
Unregisters multiple text fields.
Parameter:
- textFields: Array of field instances to detach.
Usage:
collector.unsubscribeTextFields([cardField, expField])Declaration
Swift
@MainActor public func unsubscribeTextFields(_ textFields: [VGSTextField]) -
Unregisters all currently registered text fields.
Purpose: Simplify form teardown (e.g. view controller disappearing) to prevent accidental resubmission.
Usage:
collector.unsubscribeAllTextFields()Declaration
Swift
@MainActor public func unsubscribeAllTextFields()
-
Detaches all selected/attached files from this collector.
Purpose: Free ephemeral memory and avoid unintended re-use of stale file data after successful upload or cancellation.
Behavior: Safe to call multiple times; subsequent invocations are no-ops once files are cleared.
Usage:
collector.sendFile(path: "/post") { resp in if case .success = resp { collector.cleanFiles() } }Declaration
Swift
@MainActor public func cleanFiles()
-
Callback invoked immediately before the SDK starts the asynchronous card attributes lookup.
Triggered when the user types the 11th digit in a field with
configuration.type = .cardNumber. Use this to update your UI state (e.g., disable submit button, show spinner).Declaration
Swift
@MainActor public var willBeginCardAttributesLookup: (() -> Void)? -
Callback invoked when attributes are successfully parsed from a successful lookup response.
Use this convenience callback to populate UI with bank logos, card type labels, etc. For raw response bytes, use
cardAttributesLookupResponse.Declaration
Swift
@MainActor public var didRetrieveCardAttributes: (([String : Any]) -> Void)?Parameters
attributesParsed lookup payload object.
-
Callback invoked when the lookup request completes.
Use this when you need the raw HTTP response data for both success and failure cases.
Declaration
Swift
@MainActor public var cardAttributesLookupResponse: ((VGSCardAttributesLookupResponse) -> Void)?Parameters
responseRaw lookup response result.
-
Callback invoked when the attributes lookup fails.
Follows the same payload shape as
VGSResponse.failure(code, data, response, error).Declaration
Swift
@MainActor public var didFailToRetrieveCardAttributes: ((Int, Data?, URLResponse?, Error?) -> Void)? -
Callback to request a fresh JWT token for VGS API authentication.
The SDK calls this when it needs to authenticate the lookup request. You must call the provided
completionblock with your token or an error.Declaration
Swift
@MainActor public var authHandler: ((_ completion: @escaping (Result<String, Error>) -> Void) -> Void)?
-
Creates a card through CMP using
authHandlerand the in-memory JWT cache.Declaration
Swift
@MainActor public func createCard(extraData: [String: Any]? = nil, completion block: @escaping (VGSResponse) -> Void)Parameters
extraDataAdditional CMP card attributes. Supply the contents of
data.attributes; the SDK adds the JSON:API envelope. Attribute names and value types must match the Card Management API schema or CMP can return a4xxresponse. -
Creates a card through CMP using an explicit access token.
Declaration
Swift
@MainActor public func createCard(token: String, extraData: [String: Any]? = nil, completion block: @escaping (VGSResponse) -> Void)Parameters
tokenCard Management API access token.
extraDataAdditional CMP card attributes. Supply the contents of
data.attributes; the SDK adds the JSON:API envelope. Attribute names and value types must match the Card Management API schema or CMP can return a4xxresponse.
-
Updates a card through CMP using
authHandlerand the in-memory JWT cache.Declaration
Swift
@MainActor public func updateCard(cardId: String, extraData: [String: Any]? = nil, completion block: @escaping (VGSResponse) -> Void) -
Updates a card through CMP using an explicit access token.
Declaration
Swift
@MainActor public func updateCard(cardId: String, token: String, extraData: [String: Any]? = nil, completion block: @escaping (VGSResponse) -> Void)
-
Send data from VGSTextFields to your organization vault.
- path: Inbound route path for your organization vault.
- method: VGSCollectHTTPMethod, default is
.post. - routeId: id of VGS Proxy Route, default is
nil. - extraData: Any data you want to send together with data from VGSTextFields , default is
nil. - requestOptions:
VGSCollectRequestOptionsobject, holds additional request options. Default options are.nestedJSON. completion: response completion block, returns
VGSResponse.
Note
Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.Declaration
Swift
@MainActor public func sendData(path: String, method: VGSCollectHTTPMethod = .post, routeId: String? = nil, extraData: [String : Any]? = nil, requestOptions: VGSCollectRequestOptions = VGSCollectRequestOptions(), completion block: @escaping (VGSResponse) -> Void) -
Send file to your organization vault. Only send one file at a time.
- path: Inbound route path for your organization vault.
- method: HTTPMethod, default is
.post. - routeId: id of VGS Proxy Route, default is
nil. - extraData: Any data you want to send together with data from VGSTextFields , default is
nil. completion: response completion block, returns
VGSResponse.
Note
Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.Declaration
Swift
@MainActor public func sendFile(path: String, method: VGSCollectHTTPMethod = .post, routeId: String? = nil, extraData: [String : Any]? = nil, requestOptions: VGSCollectRequestOptions = VGSCollectRequestOptions(), completion block: @escaping (VGSResponse) -> Void)
-
Send tokenization request with data from VGSTextFields to Vault API v1.
- routeId: id of VGS Proxy Route, default is
nil. - completion: response completion block, returns
VGSTokenizationResponse.
Declaration
Swift
@MainActor public func tokenizeData(routeId: String? = nil, completion block: @escaping (VGSTokenizationResponse) -> Void) - routeId: id of VGS Proxy Route, default is
-
Create aliases from VGSTextFields input with Vault API v2.
Note
Requires
Requiresset in custom headers. - Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.
Declaration
Swift
@MainActor public func createAliases(routeId: String? = nil, completion block: @escaping (VGSTokenizationResponse) -> Void)Parameters
routeIdid of VGS Proxy Route, default is
nil.completionresponse completion block, returns
VGSTokenizationResponse. - Errors can be returned in the
-
Asynchronously send data from VGSTextFields to your organization vault.
Note
Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.Declaration
Swift
@MainActor public func sendData(path: String, method: VGSCollectHTTPMethod = .post, routeId: String? = nil, extraData: [String : Any]? = nil, requestOptions: VGSCollectRequestOptions = VGSCollectRequestOptions()) async -> VGSResponseParameters
pathInbound route path for your organization vault.
methodVGSCollectHTTPMethod, default is
.post.routeIdid of VGS Proxy Route, default is
nil.extraDataAny data you want to send together with data from VGSTextFields , default is
nil.requestOptionsVGSCollectRequestOptionsobject, holds additional request options. Default options are.nestedJSON.Return Value
-
sendFile(path:Asynchronousmethod: routeId: extraData: ) Asynchronously send file to your organization vault. Only send one file at a time.
Note
Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.Declaration
Swift
@MainActor public func sendFile(path: String, method: VGSCollectHTTPMethod = .post, routeId: String? = nil, extraData: [String : Any]? = nil) async -> VGSResponseParameters
pathInbound route path for your organization vault.
methodHTTPMethod, default is
.post.routeIdid of VGS Proxy Route, default is
nil.extraDataAny data you want to send together with data from VGSTextFields , default is
nil.completionresponse completion block, returns
VGSResponse. -
createAliases(routeId:Asynchronous) Asynchronously send request with data from VGSTextFields to create aliases.
Note
Requires
Requiresset in custom headers. - Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.
Declaration
Swift
@MainActor public func createAliases(routeId: String? = nil) async -> VGSTokenizationResponseParameters
routeIdid of VGS Proxy Route, default is
nil.completionresponse completion block, returns
VGSTokenizationResponse. - Errors can be returned in the
-
tokenizeData(routeId:Asynchronous) Asynchronously send tokenization request with data from VGSTextFields.
Declaration
Swift
@MainActor public func tokenizeData(routeId: String? = nil) async -> VGSTokenizationResponseParameters
routeIdid of VGS Proxy Route, default is
nil.completionresponse completion block, returns
VGSTokenizationResponse.
-
Send data from VGSTextFields to your organization vault using the Combine framework.
Note
Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.Declaration
Swift
@MainActor public func sendDataPublisher(path: String, method: VGSCollectHTTPMethod = .post, routeId: String? = nil, extraData: [String : Any]? = nil, requestOptions: VGSCollectRequestOptions = VGSCollectRequestOptions()) -> Future<VGSResponse, Never>Parameters
pathInbound route path for your organization vault.
methodVGSCollectHTTPMethod, default is
.post.routeIdid of VGS Proxy Route, default is
nil.extraDataAny data you want to send together with data from VGSTextFields , default is
nil.requestOptionsVGSCollectRequestOptionsobject, holds additional request options. Default options are.nestedJSON.Return Value
A
Futurepublisher that emits a singleVGSResponse. -
Send file to your organization vault using the Combine framework.
Note
Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.Declaration
Swift
@MainActor public func sendFilePublisher(path: String, method: VGSCollectHTTPMethod = .post, routeId: String? = nil, extraData: [String : Any]? = nil, requestOptions: VGSCollectRequestOptions = VGSCollectRequestOptions()) -> Future<VGSResponse, Never>Parameters
pathInbound route path for your organization vault.
methodVGSCollectHTTPMethod, default is
.post.routeIdid of VGS Proxy Route, default is
nil.extraDataAny data you want to send together with data from VGSTextFields , default is
nil.requestOptionsVGSCollectRequestOptionsobject, holds additional request options. Default options are.nestedJSON.Return Value
A
Futurepublisher that emits a singleVGSResponse. -
Send request with data from VGSTextFields to create aliases using the Combine framework.
Note
Requires
Requiresset in custom headers. - Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.
Declaration
Swift
@MainActor public func createAliasesPublisher(routeId: String? = nil) -> Future<VGSTokenizationResponse, Never>Parameters
routeIdid of VGS Proxy Route, default is
nil.Return Value
A
Futurepublisher that emits a singleVGSTokenizationResponse. - Errors can be returned in the
-
Send tokenization request with data from VGSTextFields to your organization vault using the Combine framework.
Note
Errors can be returned in the
NSURLErrorDomainandVGSCollectSDKErrorDomain.Declaration
Swift
@MainActor public func tokenizeDataPublisher(routeId: String? = nil) -> Future<VGSTokenizationResponse, Never>Parameters
routeIdid of VGS Proxy Route, default is
nil.Return Value
A
Futurepublisher that emits a singleVGSTokenizationResponse.
View on GitHub