Skip to main content

iOS Element Types

TextElementUITextField

The TextElementUITextField element type enables collecting user String data. Mask and transform capabilities are available to be configured on these elements.

import Foundation
import UIKit
import BasisTheoryElements
import Combine

class TokenizeName: UIViewController {
@IBOutlet weak var nameTextField: TextElementUITextField!
@IBOutlet weak var output: UITextView!

@IBAction func tokenize(_ sender: Any) {
let body: [String: Any] = [
"data": [
"name": self.nameTextField,
],
"type": "token"
]

BasisTheoryElements.tokenize(body: body, apiKey: config.btApiKey!) { data, error in
guard error == nil else {
self.output.text = "There was an error!"
print(error)
return
}

let stringifiedData = String(data: try! JSONSerialization.data(withJSONObject: data!.value as! [String: Any], options: .prettyPrinted), encoding: .utf8)!

self.output.text = stringifiedData
print(stringifiedData)
}
}
}

Configuration

The TextElementUITextField extends the native UITextField from UIKit, so all standard properties and methods supported by UITextField are supported by TextElementUITextField.

Properties

The following additional properties are supported when programmatically interacting with a TextElementUITextField:

NameType
validationNo default validation. Validation can be overridden.
maskNo default mask. Mask can be overridden.
transformNo default transform. Transform can be overridden.
enableCopyenableCopy defaults to false and can be overriden.
copyIconColorcopyIconColor defaults to UIColor.blue and can be overriden.
getValueTypegetValueType defaults to .string and can be overriden.
TextElementUITextField extends the native iOS UITextField from UIKit, so all standard properties and attributes supported by UITextField are supported by TextElementUITextField.

Methods

SignatureDescription
setValue(elementValueReference: ElementValueReference)Sets the element's text to the value referenced by the provided ElementValueReference.
setValueRef(element: TextElementUITextField)Binds the provided element: TextElementUITextField instance as a value source for this element, keeping the value of this element in sync with any changes made to the other element.
TextElementUITextField extends the native iOS UITextField from UIKit, so all standard methods supported by UITextField are supported by TextElementUITextField.

CardNumberUITextField

The CardNumberUITextField element type renders a card number input featuring automatic brand detection, input validation, and masking. The input must be Luhn valid and be an acceptable length for the card brand.

import Foundation
import UIKit
import BasisTheoryElements
import Combine

class TokenizeCardNumber: UIViewController {
@IBOutlet weak var cardNumberTextField: CardNumberUITextField!
@IBOutlet weak var output: UITextView!

@IBAction func tokenize(_ sender: Any) {
let body: [String: Any] = [
"data": [
"number": self.cardNumberTextField,
],
"type": "token"
]

BasisTheoryElements.tokenize(body: body, apiKey: config.btApiKey!) { data, error in
guard error == nil else {
self.output.text = "There was an error!"
print(error)
return
}

let stringifiedData = String(data: try! JSONSerialization.data(withJSONObject: data!.value as! [String: Any], options: .prettyPrinted), encoding: .utf8)!

self.output.text = stringifiedData
print(stringifiedData)
}
}
}

Configuration

The CardNumberUITextField element type extends the TextElementUITextField and UITextField class, so all properties and methods supported by TextElementUITextField and UITextField are also supported here.

By default, this element is configured with:

ConfigurationDefaults
validationInput must be Luhn valid and be an acceptable length for the card brand.
maskThe mask changes depending on the card brand identified for this input according to the card brand.
transformThe transform removes all spaces set by the mask before tokenization.
enableCopyenableCopy defaults to false and can be overriden.
copyIconColorcopyIconColor defaults to UIColor.blue and can be overriden.
getValueTypegetValueType defaults to .string and can be overriden.

Card Brands

The first several digits of the card number are analyzed as the user is typing to determine the card brand. The brand is used to automatically set a mask to a brand-specific format. If the CardNumberUITextField is bound to a CardVerificationCodeUITextField, a mask is also automatically set on the CardVerificationCodeElement based on the brand's CVC length requirements.

Supported card brands are defined in the table below:

BrandIdentifierCard Number DigitsCVC Digits
American ExpressamericanExpress154
Diners ClubdinersClub14, 16, 193
Discoverdiscover16, 193
Eloelo163
Hiperhiper163
HiperCardhipercard163
JCBjcb16-193
Maestromaestro12-193
Mastercardmastercard163
MIRmir16-193
UnionPayunionPay14-193
Visavisa16, 18, 193
Some card brands have issued card numbers with multiple lengths. The Card Number Digits column documents all acceptable card number lengths for the brand (in number of digits, excluding formatting characters).

Customizing Card Brands

You can extend default card brands to include additional BIN numbers or create custom card brands by modifying the cardType property of the CardNumberUITextField.

Overriding existing card brands

...
@IBOutlet weak var cardNumberTextField: CardNumberUITextField!

var defaultWithCustomVisaCard = CardBrand.DefaultCardBrands.filter { $0.cardBrandName != CardBrandName.visa }

defaultWithCustomVisaCard.append(CardBrandDetails(cardBrandName: CardBrandName.visa, cardIdentifiers: [4, 8405],
cvcMaskInput: [try! NSRegularExpression(pattern: "\\d"), try! NSRegularExpression(pattern: "\\d"), try! NSRegularExpression(pattern: "\\d")],
gaps: [4, 8, 12], validLengths: [16, 18, 19]))

cardNumberTextField.cardTypes = defaultWithCustomVisaCard

When adding custom card brands the default list is replaced, and validation will only run against those brands defined in the cardTypes list.

For more granular control, we expose card brands individually and a list with all the default card brands.

CardExpirationDateUITextField

The CardExpirationDateUITextField element type features a month and year formatted input with validation. The input must be the current month and year or later.

import Foundation
import UIKit
import BasisTheoryElements
import Combine

class TokenizeCardExpirationDate: UIViewController {
@IBOutlet weak var expirationDateTextField: CardExpirationDateUITextField!
@IBOutlet weak var output: UITextView!

@IBAction func tokenize(_ sender: Any) {
let body: [String: Any] = [
"data": [
"expiration_month": self.expirationDateTextField.month(),
"expiration_year": self.expirationDateTextField.year(),
],
"type": "token"
]

BasisTheoryElements.tokenize(body: body, apiKey: config.btApiKey!) { data, error in
guard error == nil else {
self.output.text = "There was an error!"
print(error)
return
}

let stringifiedData = String(data: try! JSONSerialization.data(withJSONObject: data!.value as! [String: Any], options: .prettyPrinted), encoding: .utf8)!

self.output.text = stringifiedData
print(stringifiedData)
}
}
}

Configuration

The CardExpirationDateUITextField element type extends the TextElementUITextField and UITextField class, so all properties and methods supported by TextElementUITextField and UITextField are also supported here.

By default, this element is configured with:

ConfigurationDefaults
validationInput must be the current month and year or later.
maskThe mask is two digits followed by a forward slash followed by two more digits (eg. MM/YY ).
transformNo default transform.
enableCopyenableCopy defaults to false and can be overriden.
copyIconColorcopyIconColor defaults to UIColor.blue and can be overriden.
getValueTypegetValueType defaults to .string and can be overriden.

Month and Year

Both the month and year values need to be retrieved from a CardExpirationDateUITextField with the month() and year() functions, respectively. Below is an example:

let body: [String: Any] = [
"data": [
"number": self.cardNumberTextField,
"expiration_month": self.expirationDateTextField.month(),
"expiration_year": self.expirationDateTextField.year(),
"cvc": self.cvcTextField
],
"type": "card"
]
Before SDK version 3.0.0 the month() and year() methods rendered as String when sending the value to the API. As of version 3.0.0, these methods now render as Int when sending the value to the API.

Format

format(dateFormat: String) allows you to customize card expiration dates. It implements Swift's DateFormatter, so all date formats supported by it are also available.

    // expirationDateTextField value is 04/25

let body: [String: Any] = [
"data": [
"expiration_date1": self.expirationDateTextField.format(dateFormat: "yyyy-MM"), // 2025-04
"expiration_date2": self.expirationDateTextField.format(dateFormat: "MM"), // 04
"expiration_date3": self.expirationDateTextField.format(dateFormat: "M"), // 4
"expiration_date4": self.expirationDateTextField.format(dateFormat: "MM/yyyy"), // 04/2025
"expiration_date5": self.expirationDateTextField.format(dateFormat: "yy"), // 25
],
"type": "token"
]
This code example uses Basis Theory HTTP Client

CardVerificationCodeUITextField

The CardVerificationCodeUITextField element type is used to collect the card verification code.

import Foundation
import UIKit
import BasisTheoryElements
import Combine

class TokenizeCVC: UIViewController {
@IBOutlet weak var cvcTextField: CardVerificationCodeUITextField!
@IBOutlet weak var output: UITextView!

@IBAction func tokenize(_ sender: Any) {
let body: [String: Any] = [
"data": [
"cvc": self.cvcTextField,
],
"type": "token"
]

BasisTheoryElements.tokenize(body: body, apiKey: config.btApiKey!) { data, error in
guard error == nil else {
self.output.text = "There was an error!"
print(error)
return
}

let stringifiedData = String(data: try! JSONSerialization.data(withJSONObject: data!.value as! [String: Any], options: .prettyPrinted), encoding: .utf8)!

self.output.text = stringifiedData
print(stringifiedData)
}
}
}

Configuration

The CardVerificationCodeUITextField element type extends the TextElementUITextField and UITextField class, so all properties and methods supported by TextElementUITextField and UITextField are also supported here.

By default, this element is configured with:

ConfigurationDefaults
validationNo default validation. Always valid in ElementEvent.
maskIf not associated with a CardNumberUITextField, the mask is a 4 digit number. If it is, the mask changes depending on the card brand identified by the CardNumberUITextField. Refer to the section below.
transformNo default transform.
enableCopyenableCopy defaults to false and can be overriden.
copyIconColorcopyIconColor defaults to UIColor.blue and can be overriden.

Associating a CardNumberUITextField

Associating a CardNumberUITextField with a CardVerificationCodeUITextField will enhance masking capabilities of the CVC element. By default, a CardVerificationCodeUITextField mask is a 4-digit number. But when associated with a CardNumberUITextField, the mask will change to match the card brand identified by the CardNumberUITextField. Below is an example of how to make that association:

cvcTextField.setConfig(
options: CardVerificationCodeOptions(
cardNumberUITextField: cardNumberTextField
)
)

Collecting Card Data Example

See below for an example that uses all the card-related mobile elements, CardNumberUITextField, CardExpirationDateUITextField, and CardVerificationCodeUITextField together.

Note that when these card-related elements are grouped together in a dictionary, as shown in the value of data below, the token type of card should be used.
import Foundation
import UIKit
import BasisTheoryElements
import Combine

class TokenizeBillingInformationViewController: UIViewController {
@IBOutlet weak var cardNumberTextField: CardNumberUITextField!
@IBOutlet weak var expirationDateTextField: CardExpirationDateUITextField!
@IBOutlet weak var cvcTextField: CardVerificationCodeUITextField!
@IBOutlet weak var output: UITextView!

private var cancellables = Set<AnyCancellable>()

@IBAction func tokenize(_ sender: Any) {
let body: [String: Any] = [
"data": [
"number": self.cardNumberTextField,
"expiration_month": self.expirationDateTextField.month(),
"expiration_year": self.expirationDateTextField.year(),
"cvc": self.cvcTextField
],
"type": "card"
]

BasisTheoryElements.tokenize(body: body, apiKey: config.btApiKey!) { data, error in
guard error == nil else {
self.output.text = "There was an error!"
print(error)
return
}

let stringifiedData = String(data: try! JSONSerialization.data(withJSONObject: data!.value as! [String: Any], options: .prettyPrinted), encoding: .utf8)!

self.output.text = stringifiedData
print(stringifiedData)
}
}

override func viewDidLoad() {
super.viewDidLoad()

let cvcOptions = CardVerificationCodeOptions(cardNumberUITextField: cardNumberTextField)
cvcTextField.setConfig(options: cvcOptions)

cardNumberTextField.subject.sink { completion in
print(completion)
} receiveValue: { message in
print("cardNumberTextField:")
print(message)
}.store(in: &cancellables)

expirationDateTextField.subject.sink { completion in
print(completion)
} receiveValue: { message in
print("expirationDateTextField:")
print(message)
}.store(in: &cancellables)

cvcTextField.subject.sink { completion in
print(completion)
} receiveValue: { message in
print("cvcTextField:")
print(message)
}.store(in: &cancellables)
}
}