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 | Defaults |
---|---|
validation | No default validation. Always valid in ElementEvent. |
mask | No default mask. Mask can be overridden. |
transform | No default transform. Transform can be overriden. |
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 | 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. |
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 | american-express | 15 | 4 |
Diners Club | diners-club | 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 |
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).
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 | 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. |
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"
]
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 | 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. |
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)
}
}