iOS SDK
#
Installation#
Cocoapods- Set the dependency in your
Podfile
as follows:pod 'UnitComponents', '0.9.0'
- Execute
pod install
in Terminal.
#
Usage#
Unit SDK Manager classIn order to interact with Unit's SDK, use the UnitSDK.manager
class:
let manager = UnitSDK.manager
#
Setup SDK parameters#
Customer TokenSet your customer token as follows:
manager.customerToken = "token"
#
EnvironmentThe UNEnvironment
enum should be used:
public enum UNEnvironment { case sandbox case production}
Set the UNEnvironment
as follows:
manager.environment = .sandbox
#
Setup UI parameters#
Setting Manager Properties During InitializationIt is essential to note that the manager's setters should only be invoked during the initial phase of your application. This approach aims to eliminate the need for your application to wait for resource loading, thereby enhancing operational efficiency.
Parameters that have a global impact, such as the theme JSON or fonts, should be exclusively set during the initialization of our SDK. Failure to adhere to this guideline may result in inconsistent behavior throughout the application.
In certain cases, it may be permissible to define new themes or other parameters at a component level. Such alterations can be accomplished by providing the requisite parameters as arguments when initializing the specific component.
In particular, the best practice is to define it in the AppDelegate
file, as follow:
@mainclass AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let manager: UNManagerProtocol = UnitSDK.manager manager.environment = .sandbox manager.customerToken = customerToken
return true }
#
ThemeThe theme is a URL that specifies the UI configuration. Set the theme as follows:
manager.ui.setTheme("https://url.com")
#
LanguageThe language is a URL that specifies the language configuration. Set the language as follows:
manager.ui.setLanguage("https://url.com")
#
Web SDK Versioning Strategy GuideIt's essential to understand that this SDK utilizes the web SDK views for certain components.
To give you optimal flexibility in managing the Web SDK versions, we've devised a strategy that allows you to either keep your SDK up-to-date or fixate on a particular version.
To set your preferred versioning approach, utilize the enum UNWebVersioningStrategy
. Below are the options you can select from:
Exact Versioning -
exact(major: 1, minor: 1, patch: 3)
- This method allows you to lock onto a specific version that suits your needs.
Up to Next Minor -
upToNextMinor(major: 1, minor: 2)
- This is the default and recommended approach. While it keeps your SDK updated with minor patches, a manual update is needed for minor version changes.
Up to Next Major -
upToNextMajor(major: 1)
- With this strategy, your SDK will automatically update until there's a major version change.
For a comprehensive understanding, refer to our Web SDK - Versioning Guide.
manager.webVersioningStrategy = .exact(major: 1, minor: 2, patch: 2)
For the latest SDK, the latest webVersioningStrategy is upToNextMinor(major: 1, minor: 3)
.
#
Fonts#
Add the Font File to Your Project- Locate the
.ttf
or.otf
font file you wish to add. - Drag and drop the font file into your Xcode project. Make sure to check the "Copy items if needed" option and add it to your desired target.
Info.plist
#
Edit You need to register the custom font by adding the "Fonts provided by application" key in the Info.plist
file.
typealias UNFonts
as shown below:#
Now, You can configure custom fonts in your application by utilizing the public typealias UNFonts = [UNFontFamilyName: [UNFontData]]public typealias UNFontFamilyName = String
In this dictionary, the keys typically represent the font family names. Corresponding to each font family name, there is an array containing various fonts from that particular family.
<font-family>-<font-weight>
.#
Note: Our current implementation supports font names formatted as UNFontData
Properties#
Name | Type | Description |
---|---|---|
fontWeight | FontWeight | Enum that defines the weight of the font. |
sources | [UNFontSource] | An array of UNFontSource objects. An array is used to provide fallback options. |
UNFontSource
Properties#
Name | Type | Description |
---|---|---|
fileName | String | The custom font file name, as specified in the info.plist of your target |
format | String? | (Optional) Font file format. Useful for specifying fallback behavior. |
#
Swift Code Examplemanager.ui.setFonts([ "Poppins": [ UNFontData(fontWeight: FontWeight.regular, sources: [UNFontSource(fileName: "Poppins-Regular.ttf")]), UNFontData(fontWeight: FontWeight.bold, sources: [UNFontSource(fileName: "Poppins-Bold.ttf")]) ], "Arial": [ UNFontData(fontWeight: FontWeight.regular, sources: [UNFontSource(fileName: "Arial-Regular.ttf")]), ] ])
#
ComponentsAll the components extend from UIView
.
Each component receives the callbacks
as an argument, the callbacks
is a typealias
of a method that receives a callback
enum and returns nothing.
The callback
enum has all of the possible callbacks that you can receive from this component.
UNComponents SDK includes the following UI components:
Component | Protocol | Callbacks Type |
---|---|---|
Card | UNCardView | UNCardComponentCallbacks |
ACH Credit | UNACHCreditView | UNACHCreditComponentCallbacks |
ACH Debit | UNACHDebitView | UNACHDebitComponentCallbacks |
Account | UNAccountView | UNAccountComponentCallbacks |
Activity | UNActivityView | UNActivityComponentCallbacks |
BookPayment | UNBookPaymentView | UNBookPaymentComponentCallbacks |
Check Deposit | UNCheckDepositView | UNCheckDepositComponentCallbacks |
Multiple Cards | UNMultipleCardsView | UNMultipleCardsComponentCallbacks |
In order to access the UI components, use manager.ui.views
:
let manager = UnitSDK.managerlet unViews = manager.ui.views
#
Card Component#
Component name: UNCardComponent#
Configuration parameters:Name | Type | Required | Description |
---|---|---|---|
id | String | YES | A Unit card id. |
additionalSettings | UNCardViewSettingsProtocol | NO | Advanced optional settings. |
callbacks | UNCardComponentCallbacks | NO | Callbacks to interact with the Card component. |
theme | String | NO | A URL that specifies the UI configuration. |
language | String | NO | A URL that specifies the language configuration. |
The callbacks
parameter for UNCardComponent
is of the following type:
public typealias UNCardComponentCallbacks = (_ callback: UNCardComponentCallback) -> Void
The UNCardComponentCallback
is an enum
that has the following callbacks that you can receive from a Card component:
public enum UNCardComponentCallback { case cardStatusChanged(card: UNCardData) case cardActivated(card: UNCardData) case unitOnLoad(result: Result<UNCardData, UNError>)}
To get the Card Component view, call the getCardComponent
method of UnitSDK.manager.ui.views
.
#
Example:import UIKitimport UNComponentsimport SnapKit
class CardScreen: UIViewController {
fileprivate lazy var cardComponent: UNCardView = { let unViews = UnitSDK.manager.ui.views let cardComponent = unViews.getCardComponent(id: "609414"){ callback in switch callback { case .cardStatusChanged(let card): print("Card status changed \(card)") case .cardActivated(let card): print("Card activated -> \(card)") case .unitOnLoad(let result): switch result { case .success(let card): print("Successfully loaded card. Card data: \(card)") case .failure(let error): print("Failed to load Card component. Error details: \(error)") } } } return cardComponent }()
override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white
// add the card component as a subview - using SnapKit for example view.addSubview(cardComponent) cardComponent.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide.snp.top) make.leading.trailing.equalToSuperview() } }}
#
Incoming Events:In some cases, the default menu button won't fit into the design of an application.
By using the openActionsMenu()
method, it's possible to open the card actions bottom sheet from a custom button.
Important Note: one can use the openActionsMenu() only after UNCardComponent is loaded. (can be verified by onLoad callback)
#
Example:cardComponent.openActionsMenu()
It's also possible to create your own menu and call card actions from it. Use openAction(action: UNCardMenuAction)
method and send inside an action you want to perform. Use Unit's API Docs in order to understand which actions could be applied.
#
Example:cardComponent.open(action: UNCardMenuAction.addToWallet)
You can choose to implement your own show / hide card sensitive data button. In this case use 'showSensitiveData()' method to show sensitive data and 'hideSensitiveData()' method to hide it.
#
Example:cardComponent.showSensitiveData()cardComponent.hideSensitiveData()
The additionalSettings
parameter for UNCardComponent
is of the following type:
#
UNCardViewSettingsProtocol:Name | Type | Default Value | Description |
---|---|---|---|
hideActionsMenuButton | Bool | false | Hide the actions menu buttons. |
hideCardTitle | Bool | false | Hide the Card title |
hideSensitiveDataButton | Bool | false | Hide the Sensitive data ("Show details") button |
enablePushProvisioning | Bool | false | Enables Push Provisioning in case value is set to true. |
learnMoreUrl | String | "" | A “Learn more” URL on the report lost/close card info note. |
You can use UNCardViewSettingsBuilder
to create an instance of the protocol and define your additional settings.
#
Example:let additionalSettings = UNCardViewSettingsBuilder() .hideCardTitle(true) .hideSensitiveDataButton(true) .enablePushProvisioning(true)
let unViews = UnitSDK.manager.ui.viewslet cardComponent = unViews.getCardComponent(id: "609414", additionalSettings: additionalSettings)
#
Adding a card to Apple Wallet (Optional)Start by following the Add card to wallet instructions to use this capability.
After that, set the enablePushProvisioning
with the value of true
in the Card component additionalSettings parameter.
Then, you can add a card to Apple Wallet using the "Manage Apple Wallet" tab in the Card Components's native menu or using an UNCardMenuAction.AddToWallet
Incoming event.
#
ACH Credit Component#
Component name: UNACHCreditComponent#
Configuration parameters:Name | Type | Required | Description |
---|---|---|---|
accountId | String | YES | Unit account id. The account from which money is being sent. |
additionalSettings | UNACHCreditViewSettingsProtocol | NO | Advanced optional settings. |
callbacks | UNACHCreditComponentCallbacks | NO | Callbacks to interact with the ACH Credit component. |
theme | String | NO | A URL that specifies the UI configuration. |
language | String | NO | A URL that specifies the language configuration. |
The callbacks
parameter for UNACHCreditComponent
is of the following type:
public typealias UNACHCreditComponentCallbacks = (_ callback: UNACHCreditComponentCallback) -> Void
The UNACHCreditComponentCallback
is an enum
that has the following callbacks that you can receive from an ACH Credit component:
public enum UNACHCreditComponentCallback { case onPaymentCreated(data: UNACHData) case unitOnLoad(result: Result<UNACHCreditOnLoadResponse, UNError>)}
To get the ACH Credit Component call the getACHCreditComponent
method of UnitSDK.manager.ui.views
.
#
Example:import UIKitimport UNComponentsimport SnapKit
class ACHCreditScreen: UIViewController {
fileprivate lazy var achCreditComponent: UNACHCreditView = { let unViews = UnitSDK.manager.ui.views
let achCreditComponent = unViews.getACHCreditComponent(accountId: "424242"){ callback in switch callback { case .onPaymentCreated(let data): print("ACH Credit - onPaymentCreated: \(data)") case .unitOnLoad(let result): switch result { case .success(let ACHCreditResponse): print("Successfully loaded ACHCredit Component. Data: \(ACHCreditResponse)") case .failure(let error): print("Failed to load ACHCredit component. Error details: \(error)") } } } return achCreditComponent }()
override func viewDidLoad() { super.viewDidLoad()
// add the ach credit component as a subview - using SnapKit for example view.addSubview(achCreditComponent) achCreditComponent.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide.snp.top) make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom) make.leading.trailing.equalToSuperview() } }}
The additionalSettings
parameter for UNACHCreditComponent
is of the following type:
#
UNACHCreditViewSettingsProtocol:Name | Type | Default Value | Description |
---|---|---|---|
fee | Double | 0 | Bill your counterparty for his activity |
isAutoFocus | Bool | false | Auto-focus the 'add new recipient' button once the component is mounted |
withPlaid | Bool | false | Using the Plaid API to connect your users' financial accounts. Default false |
sameDay | Bool | false | Enables Same Day ACH |
#
Plaid integration:If you wish to use the Plaid API to connect your users' financial accounts using the Plaid integration. In order to utilize this integration, you must have a Plaid account and provide your Plaid credentials in the [Unit Sandbox Dashboard] (https://app.s.unit.sh/org-settings#tab=Integrations) and [Unit Production Dashboard] (https://app.unit.co/org-settings#tab=Integrations).
#
Enable camera support (for apps using Identity Verification only)If your app uses Identity Verification please follow these instructions
You can use UNACHCreditViewSettingsBuilder
to create an instance of the protocol and define your additional settings.
#
Example:let additionalSettings = UNACHCreditViewSettingsBuilder() .fee(1.5) .isAutoFocus(true) .withPlaid(true) .sameDay(true)
let unViews = UnitSDK.manager.ui.viewslet achCreditComponent = unViews.getACHCreditComponent(accountId: "424242", additionalSettings: additionalSettings)
#
ACH Debit Component#
Prerequirements:This component is using the Plaid API to connect your users' financial accounts using the Plaid integration. You must have a Plaid account and provide your Plaid credentials in the [Unit Sandbox Dashboard] (https://app.s.unit.sh/org-settings#tab=Integrations) and [Unit Production Dashboard] (https://app.unit.co/org-settings#tab=Integrations).
#
Enable camera support (for apps using Identity Verification only)If your app uses Identity Verification please follow these instructions
#
Component name: UNACHDebitComponent#
Configuration parameters:Name | Type | Required | Description |
---|---|---|---|
accountId | String | YES | Unit account id. The account from which money is being sent. |
additionalSettings | UNACHDebitViewSettingsProtocol | NO | Advanced optional settings. |
callbacks | UNACHDebitComponentCallbacks | NO | Callbacks to interact with the ACH Debit component. |
theme | String | NO | A URL that specifies the UI configuration. |
language | String | NO | A URL that specifies the language configuration. |
The callbacks
parameter for UNACHDebitComponent
is of the following type:
public typealias UNACHDebitComponentCallbacks = (_ callback: UNACHDebitComponentCallback) -> Void
The UNACHDebitComponentCallback
is an enum
that has the following callbacks that you can receive from an ACH Debit component:
public enum UNACHDebitComponentCallback { case onPaymentCreated(data: UNACHData) case unitOnLoad(result: Result<UNACHDebitOnLoadResponse, UNError>)}
To get the ACH Debit Component call the getACHDebitComponent
method of UnitSDK.manager.ui.views
.
#
Example:import UIKitimport UNComponentsimport SnapKit
class ACHDebitScreen: UIViewController {
fileprivate lazy var achDebitComponent: UNACHDebitView = { let unViews = UnitSDK.manager.ui.views
let achDebitComponent = unViews.getACHDebitComponent(accountId: "424242"){ callback in switch callback { case .onPaymentCreated(let data): print("ACH Debit - onPaymentCreated: \(data)") case .unitOnLoad(let result): switch result { case .success(let ACHDebitResponse): print("Successfully loaded ACHDebit Component. Data: \(ACHDebitResponse)") case .failure(let error): print("Failed to load ACHDebit component. Error details: \(error)") } } } return achDebitComponent }()
override func viewDidLoad() { super.viewDidLoad()
// add the ach Debit component as a subview - using SnapKit for example view.addSubview(achDebitComponent) achDebitComponent.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide.snp.top) make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom) make.leading.trailing.equalToSuperview() } }}
The additionalSettings
parameter for UNACHDebitComponent
is of the following type:
#
UNACHDebitViewSettingsProtocol:Name | Type | Default Value | Description |
---|---|---|---|
fee | Double | 0 | Bill your counterparty for his activity |
isAutoFocus | Bool | false | Auto-focus the 'add new recipient' button once the component is mounted |
sameDay | Bool | false | Enables Same Day ACH |
You can use UNACHDebitViewSettingsBuilder
to create an instance of the protocol and define your additional settings.
#
Example:let additionalSettings = UNACHDebitViewSettingsBuilder() .fee(1.5) .isAutoFocus(true) .sameDay(true)
let unViews = UnitSDK.manager.ui.viewslet achDebitComponent = unViews.getACHDebitComponent(accountId: "424242", additionalSettings: additionalSettings)
#
Account Component#
Component name: UNAccountComponent#
Configuration parameters:Name | Type | Required | Description |
---|---|---|---|
accountId | String | YES | Unit account id. The account for which the activity will be shown. |
additionalSettings | UNAccountViewSettingsProtocol | NO | Advanced optional settings. |
theme | String | NO | A URL that specifies the UI configuration. |
language | String | NO | A URL that specifies the language configuration. |
callbacks | UNAccountComponentCallbacks | NO | Callbacks to interact with the Account component. |
The callbacks
parameter for UNAccountComponent
is of the following type:
public typealias UNAccountComponentCallbacks = (_ callback: UNAccountComponentCallback) -> Void
The UNAccountComponentCallback
is an enum
that has the following callbacks that you can receive from an Account component:
public enum UNAccountComponentCallback { case unitOnLoad(result: Result<[UNAccountData], UNError>) case onAccountChange(account: UNAccountData)}
To get the Account Component call the getAccountComponent
method of UnitSDK.manager.ui.views
.
#
Example:import UIKitimport UNComponentsimport SnapKit
class AccountScreen: UIViewController {
fileprivate lazy var accountComponent: UNAccountView = { let unViews = UnitSDK.manager.ui.views let accountComponent = unViews.getAccountComponent(accountId: "424242"){ callback in switch callback { case .unitOnLoad(let result): switch result { case .success(let accounts): print("Success. Accounts Data: \(accounts)") case .failure(let error): print("Fail to load Account component. Error details: \(error)") } case .onAccountChange(let account): print(("Account \(account.id) is changed")) } } return accountComponent }()
override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(accountComponent) accountComponent.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide.snp.top) make.leading.trailing.equalToSuperview() } }
}
#
Incoming Events:In some cases, the default menu button won't fit into the design of an application.
By using the openActionsMenu()
method, it's possible to open the account actions bottom sheet from a custom button.
Important Note: one can use the openActionsMenu() only after UNAccountComponent is loaded. (can be verified by onLoad callback)
#
Example:accountComponent.openActionsMenu()
It's also possible to create your own menu and call account actions from it. Use openAction(action: UNAccountMenuAction)
method and send inside an action you want to perform. Use Unit's API Docs in order to understand which actions could be applied.
#
Example:accountComponent.open(action: UNAccountMenuAction.details)
The additionalSettings
parameter for UNAccountComponent
is of the following type:
#
UNAccountViewSettingsProtocol:Name | Type | Default Value | Description |
---|---|---|---|
hideActionsMenuButton | Bool | false | Hide the actions menu buttons. |
hideSelectionMenuButton | Bool | false | Hide selection menu button. |
You can use UNAccountViewSettingsBuilder
to create an instance of the protocol and define your additional settings.
#
Example:let additionalSettings = UNAccountViewSettingsBuilder() .hideActionsMenuButton(true) .hideSelectionMenuButton(true)
let unViews = UnitSDK.manager.ui.viewslet cardComponent = unViews.getAccountComponent(accountId: "424242", additionalSettings: additionalSettings)
#
Activity Component#
Component name: UNActivityComponent#
Configuration parameters:Name | Type | Required | Description |
---|---|---|---|
accountId | String | YES | Unit account id. The account to show. |
additionalSettings | UNActivityViewSettingsProtocol | NO | Advanced optional settings. |
callbacks | UNActivityComponentCallbacks | NO | Callbacks to interact with the Activity component. |
theme | String | NO | A URL that specifies the UI configuration. |
language | String | NO | A URL that specifies the language configuration. |
The callbacks
parameter for UNActivityComponent
is of the following type:
public typealias UNActivityComponentCallbacks = (_ callback: UNActivityComponentCallback) -> Void
The UNActivityComponentCallback
is an enum
that has the following callbacks that you can receive from an Activity component:
public enum UNActivityComponentCallbacks { case unitOnLoad(result: Result<Void, UNError>)}
To get the Activity Component view call the getActivityComponent
method of UnitSDK.manager.ui.views
.
#
Example:
class ActivityScreen: UIViewController { let unViews = UnitSDK.manager.ui.views
fileprivate lazy var activityComponent: UNActivityView = { let activityComponent = unViews.getActivityComponent(accountId: accountId){ callback in switch callback { case .unitOnLoad(let result): switch result { case .success(): print("Successfully load Activity Component.") case .failure(let error): print("Failed to load ACHCredit component. Error details: \(error)") } } } return activityComponent}()
override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(activityComponent) activityComponent.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide.snp.top) make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom) make.leading.trailing.equalToSuperview() } }}
The additionalSettings
parameter for UNActivityComponent
is of the following type:
#
UNActivityViewSettingsProtocol:Name | Type | Default Value | Description |
---|---|---|---|
hideFilterButton | Bool | false | Hide the filter button. |
paginationType | UNActivityComponentPaginationType | .infiniteScroll | Defines how more content is loaded. Possible values: .infiniteScroll , .pagination |
transactionsPerPage | Int | 8 for pagination and 15 for infinite scroll | Number of transactions to fetch on each page or scroll to bottom. Also acts as initial number of transactions to fetch |
You can use UNActivityViewSettingsBuilder
to create an instance of the protocol and define your additional settings.
#
Example:let additionalSettings = UNActivityViewSettingsBuilder() .hideFilterButton(true) .paginationType(.pagination) .transactionsPerPage(4)
let unViews = UnitSDK.manager.ui.viewslet cardComponent = unViews.getActivityComponent(accountId: accountId, additionalSettings: additionalSettings)
#
Check Deposit Component#
Component name: UNCheckDepositComponent#
Prerequirements:Check Deposit Component requires camera access. In order to enable this functionality, you need to include the Privacy - Camera Usage Description
key in your info.plist
file.
The value should be the text that will be displayed when the app prompts the user for camera access.
#
Configuration parameters:Name | Type | Required | Description |
---|---|---|---|
accountId | String | YES | Unit account id. The account to deposit to. |
fee | Double | YES | Fee changed for making the check deposit, will be presented to the user. |
callbacks | UNCheckDepositComponentCallbacks | NO | Callbacks to interact with the Activity component. |
theme | String | NO | A URL that specifies the UI configuration. |
language | String | NO | A URL that specifies the language configuration. |
The callbacks
parameter for UNCheckDepositComponent
is of the following type:
public typealias UNCheckDepositComponentCallbacks = (_ callback: UNCheckDepositComponentCallback) -> Void
The UNCheckDepositComponentCallback
is an enum
that has the following callbacks that you can receive from a Book Payment component:
Key | Type | Description |
---|---|---|
unitCheckDepositCreated | (depositCheckData: UNCheckDeposit) => Void | Occurs when a check deposit is successfully created |
unitCheckDepositRestartRequest | (depositCheckData: UNCheckDeposit) => Void | Occurs when "Deposit another check" is clicked |
unitOnLoad | (result: Result<UNAccountData, UNError>) => Void | Callback for a loaded component |
To get the Check Deposit Component view call the getCheckDepositComponent
method of UnitSDK.manager.ui.views
.
#
Example:import UIKitimport UNComponentsimport SnapKit
class CheckDepositScreen: UIViewController {
fileprivate lazy var checkDepositComponent: UNCheckDepositView = { let unViews = UnitSDK.manager.ui.views
let checkDepositComponent = unViews.getCheckDepositComponent(accountId: "424242", fee: 1.5) { callback in switch callback { case .unitCheckDepositCreated(let checkData): print("Check deposit created, data: \(checkData)") case .unitCheckDepositRestartRequest(let checkData): print("Check deposit restart request \(checkData)") case .unitOnLoad(let accountData): print("CheckDeposit Component is loaded. Account: \(accountData)") } } return checkDepositComponent }()
override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(checkDepositComponent) checkDepositComponent.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide.snp.top) make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom) make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading) make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing) } }}
#
Book Payment Component#
Component name: UNBookPaymentComponent#
Configuration parameters:Name | Type | Required | Description |
---|---|---|---|
accountId | String | YES | Unit account id. The account from which money is being sent. |
counterpartyAccountId | String | YES | Unit account id. The account which will receive money. |
counterpartyName | String | YES | Name of the counterparty. This is the name that will be displayed in the Book Payment UI during the transfer. |
isSameCustomer | Bool | No | Stating whether both accounts belong to the same customer. Allows fetching additional information about the counterparty account. Default false. |
additionalSettings | UNBookPaymentViewSettingsProtocol | NO | Advanced optional settings. |
callbacks | UNBookPaymentComponentCallbacks | NO | Callbacks to interact with the Book Payment component. |
theme | String | NO | A URL that specifies the UI configuration. |
language | String | NO | A URL that specifies the language configuration. |
The callbacks
parameter for UNBookPaymentComponent
is of the following type:
public typealias UNBookPaymentComponentCallbacks = (_ callback: UNBookPaymentComponentCallback) -> Void
The UNBookPaymentComponentCallback
is an enum
that has the following callbacks that you can receive from a Book Payment component:
public enum UNBookPaymentComponentCallback { case onPaymentCreated(data: UNBookPaymentData) case unitOnLoad(result: Result<UNAccountData, UNError>)}
To get the Book Payment Component view, call the getBookPaymentComponent
method of UnitSDK.manager.ui.views
.
#
Example:import UIKitimport UNComponentsimport SnapKit
class BookPaymentScreen: UIViewController {
fileprivate lazy var bookPaymentComponent: UNBookPaymentView = { let unViews = UnitSDK.manager.ui.views let bookPaymentComponent = unViews.getBookPaymentComponent(accountId: "1105561", counterpartyAccountId: "1105562", counterpartyName: "Peter Parker") { callback in switch callback { case .onPaymentCreated(let data): print("[Book Payment Screen] onPaymentCreated: \(data)") case .unitOnLoad(let result): switch result { case .success(let account): print("Success Loading Book Payment. account: \(account)") case .failure(let error): switch error { case .onLoad(let onLoadErrors): print("Fail to load Book Payment component. Errors:") for loadError in onLoadErrors { print("Status: \(loadError.status); Title:\(loadError.title)") } default: print("Error: \(error.description)") } } } } return bookPaymentComponent }()
override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white
// add the book payment component as a subview - using SnapKit for example view.addSubview(bookPaymentComponent) bookPaymentComponent.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide.snp.top) make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom) make.leading.trailing.equalToSuperview() } }}
The additionalSettings
parameter for UNBookPaymentComponent
is of the following type:
#
UNBookPaymentViewSettingsProtocol:Name | Type | Default Value | Description |
---|---|---|---|
isAutoFocus | Bool | false | Auto-focus the money input field once the component is mounted. |
You can use UNBookPaymentViewSettingsBuilder
to create an instance of the protocol and define your additional settings.
#
Example:let additionalSettings = UNBookPaymentViewSettingsBuilder() .isAutoFocus(true)
let unViews = UnitSDK.manager.ui.viewslet bookPaymentComponent = unViews.getBookPaymentComponent(accountId: "1105561", counterpartyAccountId: "1105562", counterpartyName: "Peter Parker", additionalSettings: additionalSettings)
#
Multiple Cards Component#
Component name: UNMultipleCardsComponent#
Configuration parameters:Name | Type | Required | Description |
---|---|---|---|
additionalSettings | UNMultipleCardsViewSettingsProtocol | NO | Advanced optional settings. |
callbacks | UNMultipleCardsComponentCallbacks | NO | Callbacks to interact with the Multiple Cards component. |
theme | String | NO | A URL that specifies the UI configuration. |
language | String | NO | A URL that specifies the language configuration. |
The callbacks
parameter for UNMultipleCardsComponent
is of the following type:
public typealias UNMultipleCardsComponentCallbacks = (_ callback: UNMultipleCardsComponentCallback) -> Void
The UNMultipleCardsComponentCallback
is an enum
that has the following callbacks that you can receive from a Multiple Cards component:
public enum UNMultipleCardsComponentCallback { case cardClicked(card: UNCardData) case unitOnLoad(result: Result<[UNCardData], UNError>)}
To get the Multiple Cards Component view, call the getMultipleCardsComponent
method of UnitSDK.manager.ui.views
.
#
Example:import UIKitimport UNComponentsimport SnapKit
class MultipleCardsScreen: UIViewController {
fileprivate lazy var multipleCardsComponent: UNMultipleCardsView = { let unViews = UnitSDK.manager.ui.views let multipleCardsComponent = unViews.getMultipleCardsComponent() { callback in switch callback { case let .cardClicked(card): print("Card clicked, ID: \(card.id)") case .unitOnLoad(let result): switch result { case .success(let cards): print("Success Loading Multiple Cards") case .failure(let error): print("Error Loading Multiple Cards") } } } return multipleCardsComponent }()
override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white
// add the multiple cards component as a subview - using SnapKit for example view.addSubview(multipleCardsComponent) multipleCardsComponent.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide.snp.top) make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom) make.leading.trailing.equalToSuperview() } }}
The additionalSettings
parameter for UNMultipleCardsComponent
is of the following type:
#
UNMultipleCardsViewSettingsProtocol:Name | Type | Default Value | Description |
---|---|---|---|
disableCardClick | Bool | false | When true, will not publish a unitMultipleCardsCardClicked event when a row is clicked |
paginationType | UNMultipleCardsComponentPaginationType | .infiniteScroll | Defines how more content is loaded. Possible values: .infiniteScroll , .pagination |
cardsPerPage | Int | 8 for pagination and 15 for infinite scroll | Number of cards to fetch on each page or scroll to bottom. Also acts as initial number of cards to fetch |
You can use UNMultipleCardsViewSettingsBuilder
to create an instance of the protocol and define your additional settings.
#
Example:let additionalSettings = UNMultipleCardsViewSettingsBuilder() .disableCardClick(true) .paginationType(.pagination) .cardsPerPage(4)
let unViews = UnitSDK.manager.ui.viewslet multipleCardsComponent = unViews.getMultipleCardsComponent(additionalSettings: additionalSettings)
#
Flows#
Add card to wallet flowStart by following the Add card to wallet instructions to use this flow.
After that, you can add a card to Apple Wallet by calling the Unit SDK's func startPushProvisioning(for cardId: String, theme: UNTheme?, language: UNLanguage?)
method.
#
Example:UnitSDK.manager.ui.flows.startPushProvisioning(for: YOUR_CARD_ID)
#
Additional Capabilities#
Add card to walletThis capability can be used with the Card Component or without it, as a separate flow.
#
PrerequirementsComplete the following steps at the Steps to support Apple Pay- Apple Pay Prerequirements:
- Request Apple Pay In-app provisioning entitlement.
- Setup your App in Apple Developer Portal once entitlement is granted by Apple.
#
Steps to integrate with the Visa SDKComplete the following integration-steps:
- Wallet Capability.
- In-App Provisioning entitlement.
- Add Visa SDK to your Xcode project.
#
Add to Wallet flowYou can find an overview of the add to wallet flow in this link.
Create a Swift
class named UNVisaProvider
. This class will be responsible to communicate and pass data from the Unit SDK and the VDE(Visa Digital Enablement) SDK through your app.
UNVisaProvider code
import Foundationimport VisaPushProvisioningimport UIKitimport UNComponentsimport VisaInAppModuleCore
internal final class UNVisaProvider: UNVisaProviding { private var provisioningInterface: VisaPushProvisioningInterface? = nil
private var initializationCallback: UNVisaInitializationCompletion? = nil private var supportedWalletsCallback: UNVisaSupportedWalletsCompletion? = nil private var cardProvisioningCallback: UNVisaCardProvisioningCompletion? = nil
init(environment: VisaInAppEnvironment, appId: String) { // Setup Visa SDK Config let visaInAppConfig = VisaInAppConfig(environment: environment, appId: appId) do { try VisaInAppCore.configure(config: visaInAppConfig) } catch { print(error) } }
func initialize(completion: @escaping UNVisaInitializationCompletion) { self.initializationCallback = completion provisioningInterface = VisaPushProvisioningInterfaceFactory.createPushProvisioningInterface( listener: self) provisioningInterface?.initialize() }
func getSupportedWallets(for payload: String, completion: @escaping UNVisaSupportedWalletsCompletion) { self.supportedWalletsCallback = completion let request = VPSupportedWalletRequest(encPayload: payload) self.provisioningInterface?.getSupportedWallets(request: request) }
func startCardProvisioning(for walletName: String, in vc: UIViewController, completion: @escaping UNVisaCardProvisioningCompletion) { self.cardProvisioningCallback = completion let request = VPCardProvisioningRequest(walletCode: VPSupportedWalletCode(rawValue: 0)!, walletName: walletName) provisioningInterface?.startCardProvisioning(request: request, initialView: vc) }}
extension UNVisaProvider: VisaPushProvisioningListener { func initializationSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPInitResponse) { self.initializationCallback?(response.signedNonce, nil) self.initializationCallback = nil }
func initializationFailure(pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) { let unError = UNVPError(code: error.code, description: error.description, type: error.type.toUNVPErrorType(), correlationId: error.correlationId) self.initializationCallback?(nil, unError) self.initializationCallback = nil }
func supportedWalletSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPSupportedWalletResponse) { self.supportedWalletsCallback?(response.wallets.map({ $0.toUNVPSupportedWallet()}), nil) self.supportedWalletsCallback = nil }
func supportedWalletFailure(pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) { self.supportedWalletsCallback?(nil, error.toUNVPError()) self.supportedWalletsCallback = nil }
func cardProvisioningSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPCardProvisioningResponse) { self.cardProvisioningCallback?(response.toUNVPCardProvisioningResponse(), nil) self.cardProvisioningCallback = nil }
func cardProvisioningFailure(pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) { self.cardProvisioningCallback?(nil, error.toUNVPError()) self.cardProvisioningCallback = nil }}
fileprivate extension VPSupportedWallet { func toUNVPSupportedWallet() -> UNVPSupportedWallet { return UNVPSupportedWallet(name: self.name, description: self.description, status: self.status.toUNVPProvisionStatus(), reason: self.reason.toUNVPReason()) }}
fileprivate extension VPReason { func toUNVPReason() -> UNVPReason { return UNVPReason(reason: self.reason, description: self.description) }}
fileprivate extension VPProvisionStatus { func toUNVPProvisionStatus() -> UNVPProvisionStatus { switch self { case .ReadyToProvision: return .readyToProvision case .AlreadyProvisioned: return .alreadyProvisioned case .ProvisionedInCurrentDevice: return .provisionedInCurrentDevice case .ProvisionedInPairedDevice: return .provisionedInPairedDevice case .NotAvailable: return .notAvailable @unknown default: return .notAvailable } }}
fileprivate extension VPCardProvisioningResponse { func toUNVPCardProvisioningResponse() -> UNVPCardProvisioningResponse { return UNVPCardProvisioningResponse(walletStatus: self.walletStatus.toUNVPProvisionStatus()) }}
fileprivate extension VPError { func toUNVPError() -> UNVPError { return UNVPError(code: self.code, description: self.description, type: self.type.toUNVPErrorType(), correlationId: self.correlationId) }}
fileprivate extension VPErrorType { func toUNVPErrorType() -> UNVPErrorType { switch self { case .EmptyAppId: return .emptyAppId case .DeviceAuthenticationFailed: return .deviceAuthenticationFailed case .DeviceRootDetection: return .deviceRootDetection case .EmptyEncryptedPayload: return .emptyEncryptedPayload case .NoWallets: return .noWallets case .InvalidCardId: return .invalidCardInfo case .InvalidCardLast4Digits: return .invalidCardLast4Digits case .ProvisioningNotAllowed: return .provisioningNotAllowed case .CancelledByUser: return .cancelledByUser case .AppleWalletProvisioningError: return .walletProvisioningError case .UnableToCreateApplePaymentPassView: return .unableToCreatePaymentPassView case .ValidAppleCertificatesNotFound: return .validCertificatesNotFound case .NetworkFailure: return .networkFailure case .SessionExpired: return .sessionExpired case .InvalidInfo: return .invalidCardInfo case .PayloadDecryptionFailed: return .payloadDecryptionFailed case .ApiError: return .apiError case .InvalidNonce: return .invalidNonce case .SDKLockout: return .sdkLockout case .WalletProvisioningInconclusive: return .walletProvisioningInconclusive case .WalletProvisioningError: return .walletProvisioningError @unknown default: return .networkFailure } }}
#
Set Unit SDK with the UNVisaProviderCall UnitSDK.manager.services.setVisaProvider
with a UNVisaProvider
instance. It is recommended to call it inside the application didFinishLaunchingWithOptions
method in the AppDelegate.swift
file. You will need to make sure you're initializing the manager.environment
with UNEnvironment.Production
environment as well. Pass the UNVisaProvider
with your Visa's App ID and a VisaInAppEnvironment.Production
environment.
#
Example:import UIKitimport UNComponentsimport VisaInAppModuleCore
@mainclass AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. let manager: UNManagerProtocol = UnitSDK.manager manager.services.setVisaProvider(UNVisaProvider(environment: VisaInAppEnvironment.Production, appId: YOUR_APP_ID))
return true } ...}
#
Error HandlingBy using unitOnLoad callback you can get a Swift.Result about the requested component. OnError - you will get an enum UNError that consists of several cases.
#
UNError:Case | fields | Description |
---|---|---|
onLoad | errors: [UNErrorResponse] | Report UNErrorResponse on errors that happen during loading time |
#
UNErrorResponse:Name | Type | Description |
---|---|---|
status | String | A Unit-specific code, uniquely identifying the error type |
title | String? | The title of the error type |
detail | String? | Additional information about the error. |
details | String? | Additional information about the error. |
meta | Meta?: { supportId: String } | meta.supportId unique error identifier to be used for further investigation |
Note: An "error object" MUST contain a title and the HTTP status code members.
#
Example:fileprivate lazy var accountComponent: UNAccountView = { let unViews = UnitSDK.manager.ui.views let accountComponent = unViews.getAccountComponent(accountId: "424242"){ callback in switch callback { case .unitOnLoad(let result): switch result { case .success(let accounts): print("Success. Accounts Data: \(accounts)") case .failure(let error): switch error { case .onLoad(let onLoadErrors): print("Fail to load Account component. Errors:") for loadError in onLoadErrors { print("Status: \(loadError.status); Title:\(loadError.title)") } } } } return accountComponent}()