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
:
Name | Type |
---|---|
validation | No default validation. Validation can be overridden. |
mask | No default mask. Mask can be overridden. |
transform | No default transform. Transform can be overridden. |
enableCopy | enableCopy defaults to false and can be overriden. |
copyIconColor | copyIconColor defaults to UIColor.blue and can be overriden. |
getValueType | getValueType 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
Signature | Description |
---|---|
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:
Configuration | Defaults |
---|---|
validation | Input must be Luhn valid and be an acceptable length for the card brand. |
mask | The mask changes depending on the card brand identified for this input according to the card brand. |
transform | The transform removes all spaces set by the mask before tokenization. |
enableCopy | enableCopy defaults to false and can be overriden. |
copyIconColor | copyIconColor defaults to UIColor.blue and can be overriden. |
getValueType | getValueType 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:
Brand | Identifier | Card Number Digits | CVC Digits |
---|---|---|---|
American Express | americanExpress | 15 | 4 |
Diners Club | dinersClub | 14, 16, 19 | 3 |
Discover | discover | 16, 19 | 3 |
Elo | elo | 16 | 3 |
Hiper | hiper | 16 | 3 |
HiperCard | hipercard | 16 | 3 |
JCB | jcb | 16-19 | 3 |
Maestro | maestro | 12-19 | 3 |
Mastercard | mastercard | 16 | 3 |
MIR | mir | 16-19 | 3 |
UnionPay | unionPay | 14-19 | 3 |
Visa | visa | 16, 18, 19 | 3 |
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 cardType
s 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:
Configuration | Defaults |
---|---|
validation | Input must be the current month and year or later. |
mask | The mask is two digits followed by a forward slash followed by two more digits (eg. MM/YY ). |
transform | No default transform. |
enableCopy | enableCopy defaults to false and can be overriden. |
copyIconColor | copyIconColor defaults to UIColor.blue and can be overriden. |
getValueType | getValueType 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"
]
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"
]
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:
Configuration | Defaults |
---|---|
validation | No default validation. Always valid in ElementEvent. |
mask | If 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. |
transform | No default transform. |
enableCopy | enableCopy defaults to false and can be overriden. |
copyIconColor | copyIconColor 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.
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)
}
}