Mobile SDK for iOS

The Apto Mobile SDK is designed to be used from a mobile app. This SDK exposes Apto Mobile API endpoints as simple-to-use methods, and the data returned by the API is properly encapsulated and easy to access.

With this SDK, you'll be able to onboard new users, issue cards, obtain card activity information, and allow users to manage the card (set PIN, freeze / unfreeze, and more).

For more information about the underlying API, see the Apto Mobile API documentation.

Requirements

  • Xcode 10
  • Swift 5
  • CocoaPods

Installation

(Using CocoaPods)

  1. In your Podfile, add the following dependency:

    platform :ios, '10.0'
    use_frameworks!
    pod 'AptoSDK'
  2. Run pod install.

Using the SDK

To run the SDK you must first register a project in order to get a API KEY. Please contact Apto to create a project for you. Then, initialise the SDK by passing the public API key:

AptoPlatform.defaultManager().initializeWithApiKey("API KEY")

This will initialise the SDK to operate in production mode. If you want to use it in sandbox mode, an additional parameter can be sent during initialization:

AptoPlatform.defaultManager().initializeWithApiKey("API KEY",
environment: .sandbox)

User session token

In order to authenticate a user and retrieve a user session token, the Apto Mobile API provides mechanisms to sign up or sign in. Both mechanisms are based on verifying the user primary credentials, which can be user's phone or email, depending on the configuration of your project. Please contact us to set up the proper primary credential for your users.

Typical steps to obtain a user token involve:

  1. Verify user's primary credential. Once verified, the verification contains data showing whether the credential belongs to an existing user or to a new user.

  2. If the credential belongs to an existing user, verify user's secondary credential. Then obtain a user session token by using the login method on the SDK. That method receives the two previous verifications. The user token will be stored and handled by the SDK.

  3. If the credential doesn't belong to an existing user, create a new user with the verified credential and obtain a user token. The user token will be stored and handled by the SDK.

Set user token

Use this method to specify a user session token (obtained using the Apto B2B API) to be used by the SDK. This is optional, if a session token is not provided, the SDK will verify the user to obtain one.

AptoPlatform.defaultManager().setUserToken("user_token")

Verifications

Start a new verification

To start a new verification, you can use the following SDK methods:

AptoPlatform.defaultManager().startPhoneVerification(phone) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let verification):
// The verification started and the user received an SMS with a single use code.
}
}
AptoPlatform.defaultManager().startEmailVerification(email) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let verification):
// The verification started and the user received an email with a single use code.
}
}

Restart a verification

Verifications can be restarted by using the following SDK method:

AptoPlatform.defaultManager().restartVerification(verification) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let verification):
// The verification started and the user received a new secret via email or phone.
}
}

Complete a verification

To complete a new verification, you can use the following SDK method:

verification.secret = pin // pin entered by the user
AptoPlatform.defaultManager().completeVerification(verification) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let verification):
if verification.status == .passed {
// The verification succeeded. If it belongs to an existing user, it will contain a non null `secondaryCredential`.
}
else {
// The verification failed: the secret is invalid.
}
}
}

User management

Create a new user

After the primary credential has been verified, you can use the following SDK method to create a new user:

// Prepare a DataPointList containing the verified user's primary credential.
let primaryCredential = PhoneNumber(countryCode, phoneNumber)
primaryCredential.verification = verification // The verification obtained before.
let userPII = DataPointList()
userPII.add(primaryCredential)
AptoPlatform.defaultManager().createUser(userData: userPII) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let user):
// The user created. It contains the user id and the user session token.
}
}

The createUser method also accepts an optional custodianUid parameter, which can be used to send Apto the ID of the user in your platform. Future notifications (webhooks) can contain that ID, making it easier for you to match the event with the user in your platform.

let custodianUid = "your_platform_user_id"
AptoPlatform.defaultManager().createUser(userData: userPII, custodianUid: custodianUid) { [weak self] result in
...
}

Log in with an existing user

After the primary and secondary credentials have been verified, you can use the following SDK method to obtain a user token for an existing user:

AptoPlatform.defaultManager().loginUserWith([phoneVerification, dobVerification]) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let user):
// The user logged in. The user variable contains the user id and the user session token.
}
}

Update user info

To update a user's info, use the following SDK method:

let userPII = DataPointList()
// Add to userPII the datapoints that you want to update
AptoPlatform.defaultManager().updateUserInfo(userPII) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let user):
// Update successful
}
}

Close user session

To close the current user's session, use the following SDK method:

AptoPlatform.defaultManager().logout()

Card program management

Get available card programs

To get a list of all the available card programs that can be used to issue cards, you can use the following SDK method:

AptoPlatform.defaultManager().fetchCardProducts() { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let cardProductSummary):
// cardProductSummary is a CardProductSummary object
}
}

Get card program details

To get the details of a specific card program, you can use the following SDK method:

AptoPlatform.defaultManager().fetchCardProduct(cardProductId) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let cardProduct):
// cardProduct is a CardProduct object
}
}

Card management

Issue a card

To issue a card, you can use the following SDK methods:

let custodian = Custodian() // Set up custodian data here. You might need to set the externalCredentials property.
AptoPlatform.defaultManager().fetchCardProducts { result in
switch result {
case .failure(let error):
// Do something with the error
case .success(let cardProducts):
// Dependong on the card program setup you might need to allow the user to select the appropriate card product
// instead of using the first one. You can use the fetchCardProduct(cardProductId:forceRefresh:callback:) method
// to get more details about the card product.
AptoPlatform.defaultManager().issueCard(cardProduct: cardProducts[0], custodian: custodian) { result in
switch result {
case .failure(let error):
// Do something with the error
case .success(let card):
// card contains the issued Card object
}
}
}
}

The issueCard method also accepts an optional additionalFields parameter that can be used to send Apto additional data required to card issuance that is not captured during the user creation process. For a list of allowed fields and values contact us. You can also use initialFundingSourceId to specify the id of the wallet that will be connected to the card when issued. Only applies to debit card programs. For additional information regarding this parameter, contact us.

let additionalFields: [String: AnyObject] = [
"field1": "value1",
"field2": 2
]
let initialFundingSourceId = "initial_funding_source_id"
AptoPlatform.defaultManager().issueCard(cardProduct: cardProduct, custodian: custodian,
additionalFields: additionalFields,
initialFundingSourceId: initialFundingSourceId) { result in
...
}

Get cards

To retrieve the user's cards, you can use the following SDK method:

AptoPlatform.defaultManager().fetchCards() { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let cards):
// cards contains an array of Card objects
}
}

Physical card activation

Physical cards need to be activated by providing an activation code that is sent to the cardholder. In order to activate the physical card, you can use this SDK method:

AptoPlatform.defaultManager().activatePhysicalCard(cardId) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let result):
// Result contains information about the activation process and, if it failed, the reason why it failed.
}
}

Change card PIN

In order to set the card PIN, you can use the following SDK method:

AptoPlatform.defaultManager().changeCardPIN(cardId, newPIN) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let card):
// Operation successful
}
}

Freeze / unfreeze card

Cards can be freezed and unfreezed at any moment. Transactions of a freezed card will be rejected in the merchant's POS. To freeze / unfreeze cards, you can ue the following SDK methods:

AptoPlatform.defaultManager().lockCard(cardId) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let card):
// Operation successful
}
}
AptoPlatform.defaultManager().unlockCard(cardId) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let card):
// Operation successful
}
}

Funding source management

Apto cards can be connected to different funding sources. You can obtain a list of the available funding sources for the current user, and connect one of them to a user's card.

Get a list of the available funding sources

AptoPlatform.defaultManager().fetchCardFundingSources(cardId) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let fundingSources):
// fundingSources contain a list of FundingSource objects.
}
}

Get the funding source connected to a card

AptoPlatform.defaultManager().fetchCardFundingSource(cardId) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let fundingSource):
// fundingSource is a FundingSource object.
}
}

Connect a funding source to a card

AptoPlatform.defaultManager().setCardFundingSource(cardId, fundingSourceId) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let fundingSource):
// Operation successful
}
}

Monthly spending stats

To obtain information about the monthly spendings of a given card, classified by category, you can use the following SDK method:

AptoPlatform.defaultManager().cardMonthlySpending(cardId, date) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let monthlySpending):
// monthlySpending contains the stats of the given month; spendings classified by transaction category and difference with the previous month.
}
}

Date represents the month of the spending stats.

Notification preferences

Users can be notified via push notifications regarding several events (transactions, card status changes, etc.). The SDK offers some functions that allow the users to decide how they receive these notifications.

Obtain the current user notification preferences

AptoPlatform.defaultManager().fetchNotificationPreferences() { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let notificationPreferences):
// notificationPreferences contains all the information regarding the current user preferences.
}
}

Update the current user notification preferences

let preferences = NotificationPreferences()
// Set the user preferences in `preferences`
AptoPlatform.defaultManager().updateNotificationPreferences(preferences) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let notificationPreferences):
// Operation successful
}
}

Transaction management

To get a list of transactions, you can use the following SDK method:

AptoPlatform.defaultManager().fetchCardTransactions(cardId, filters, forceRefresh) { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
// Do something with the error
case .success(let transactions):
// Operation successful
}
}

The filters parameter allows you to filter the type of transactions that are returned by the SDK.

The forceRefresh parameter controls whether the SDK returns the local cached transaction list or asks for the transaction list through the Apto Mobile API.

Contributing & Development

We love feedback, including new feature requests, bug fixes, and documentation improvements. If you want to help us, please take a look at the issues section in the repository first; maybe someone else had the same idea and it's an ongoing or (even better) finished task! If what you want to share with us is not in the issues section, please create a new issue and we'll get back to you as soon as possible.

If you want to help us improve our SDK by adding a new feature or fixing a bug, we'll be glad to see your pull requests!