Link iOS SDK documentation

Overview

Introduction

COPY

COPIED!

Here you find instructions on how to integrate and use Plaid Link for iOS. At the center of it lies LinkKit.framework: an embeddable framework managing the details of linking an account with Plaid.

To get up and running quickly with Plaid Link for iOS clone the GitHub repository and try out the example applications, which provide a reference implementation in Swift and Objective-C. Youʼll want to sign up for free API keys to get started.

Examples of Plaid Link for iOS

Requirements

COPY

COPIED!

  1. Integrate the LinkKit.framework into your application using CocoaPods, Carthage, or manually
  2. Add a custom Run Script build phase containing this script to run after the Embed Frameworks build phase. This prepares LinkKit.framework for distribution through the App Store.

    Note
    Failing to do so will very likely get your application rejected during App Store submission or review!
  3. Import LinkKit

  4. Adopt the PLKPlaidLinkViewDelegate protocol
  5. Implement the delegate methods
  6. Present the PLKPlaidLinkViewController

Integration


Plaid Link for iOS is an embedabble framework that is bundled and distributed within your application. There are several ways to obtain the necessary files and keep them up-to-date, we recommend using CocoaPods or Carthage. Regardless of what you choose, submitting a new version of your application with the updated LinkKit.framework to the App Store is required.

CocoaPods

COPY

COPIED!

To integrate LinkKit.framework using CocoaPods

pod install
  • Add a custom Run Script build phase (we recommend naming it Prepare for Distribution) with the script below, which prepares the LinkKit.framework for distribution through the App Store.

    Note
    Failing to do so will very likely get your application rejected during App Store submission or review!
  • To update to newer releases in the future run the following command

pod update Plaid

Carthage

COPY

COPIED!

To integrate LinkKit.framework using Carthage

  • Add binary "https://raw.githubusercontent.com/plaid/link/master/LinkKit.json" to your project's Cartfile

  • Run the following command to download the latest version of LinkKit.framework

carthage update
  • Follow the manual instructions below

Manual

COPY

COPIED!

Get the latest version of LinkKit.framework and embed it into your application. If you chose to integrate using Carthage and have followed the steps above LinkKit.framework has already been downloaded to Carthage/Build/iOS/LinkKit.framework.

Embed LinkKit.framework into your application, for example by dragging and dropping the file onto the Embed Frameworks build phase as shown below.

Embed LinkKit.framework

Depending on the location of the LinkKit.framework on the filesystem you may need to change the Framework Search Paths build setting to avoid the error: fatal error: 'LinkKit/LinkKit.h' file not found, see image below.

The LinkDemo Xcode projects have it set to FRAMEWORK_SEARCH_PATHS = $(PROJECT_DIR)/../ for example, since the LinkKit.framework file is shared between them and is kept in the directory that also contains the demo project directories.

Edit framework search paths build setting

Finally, add a Run Script build phase (we recommend naming it Prepare for Distribution) with the script below. Be sure to run this build phase after the Embed Frameworks build phase (or [CP] Embed Pods Frameworks build phase when integrating using CocoaPods), otherwise LinkKit.framework will not be properly prepared for distribution.

Note
Failing to do so will very likely get your application rejected during App Store submission or review!

Add Run Script Build Phase Edit Run Script Build Phase

The script below removes any non-iOS device code from the framework which is included to support running LinkKit in the Simulator but may not be distributed via the App Store.

Note
Failing to do so will very likely get your application rejected during App Store submission or review!

Change the ${PROJECT_DIR}/LinkKit.framework path in the example below according to your setup, and be sure to quote the filepaths when they contain whitespace.

LINK_ROOT=${PODS_ROOT:+$PODS_ROOT/Plaid/ios}
cp "${LINK_ROOT:-$PROJECT_DIR}"/LinkKit.framework/prepare_for_distribution.sh "${CODESIGNING_FOLDER_PATH}"/Frameworks/LinkKit.framework/prepare_for_distribution.sh
"${CODESIGNING_FOLDER_PATH}"/Frameworks/LinkKit.framework/prepare_for_distribution.sh

Configuration

There are two ways to configure Plaid Link for iOS:

  1. By creating a custom instance of PLKConfiguration and passing it to the PLKPlaidLinkViewController.
  2. By adding a custom entry named PLKPlaidLinkConfiguration to the Info.plist of the application and adding the following configuration items

Required items

COPY

COPIED!

Item Description
clientName
String
Displayed to the user once they have successfully linked their account
env
String
The API environment to use, see below
key
String
Your Plaid public_key available from the Plaid dashboard
product
String or Array of Strings
Select the Plaid products you would like to use, to learn more visit the Plaid Products page
Available API environments
  • sandbox: Stateful sandbox environment; use test credentials and build out and test your integration
  • development: Test your integration with live credentials; you will need to request access before you can use our Development environment
  • production: Production API environment; all requests are billed

Optional items

COPY

COPIED!

Item Description
webhook
String
The webhook will receive notifications once a userʼs transactions have been processed and are ready for use. The webhook must be a valid URL. For details refer to the Plaid API documentation.

Deprecated items

COPY

COPIED!

The following configuration items have been deprecated and will be removed in a future release.

Item Description
selectAccount
Boolean
Whether the user should select a specific account after successfully linking their bank account (default: NO).
Note: Use the Select Account view from the Dashboard to control whether or not your Link integration uses the Select Account view

In the next example the values for clientName, key, and env will be set to the value of Xcode build settings, PRODUCT_NAME usually expands to the application name, the custom build settings LINK_KEY and LINK_ENV need to be added manually in Xcode should you want to use this approach. This allows use of a different key and env per build configurations (e.g. Debug, Release).

Edit Info Plist Add Custom Build Setting

If you prefer using the commandline over adding the entries to your applicationʼs Info.plist manually, the following command adds what is necessary. Unless you are using the build settings based approach as outlined above replace $(PRODUCT_NAME), $(LINK_KEY), and $(LINK_ENV) with your specific values and replace "${PATH_TO_THE_APPLICATIONS}"/Info.plist with the path to your applicationʼs Info.plist.

/usr/libexec/PlistBuddy "${PATH_TO_THE_APPLICATIONS}"/Info.plist \
  -c 'Add PLKPlaidLinkConfiguration:clientName string $(PRODUCT_NAME)' \
  -c 'Add PLKPlaidLinkConfiguration:key string $(LINK_KEY)' \
  -c 'Add PLKPlaidLinkConfiguration:env string $(LINK_ENV)' \
  -c 'Add PLKPlaidLinkConfiguration:product string auth' \
  -c 'Add PLKPlaidLinkConfiguration:selectAccount bool NO'

Implementation

Plaid Link for iOS presents itself through the PLKPlaidLinkViewController class.

The steps to implement Plaid Link for iOS in your application are:

  1. Import LinkKit
  2. Adopt the PLKPlaidLinkViewDelegate protocol
  3. Implement the delegate methods
  4. Present the PLKPlaidLinkViewController

Import LinkKit

COPY

COPIED!

To use Plaid Link for iOS import LinkKit and its symbols into your code.

import LinkKit
#import <LinkKit/LinkKit.h>

Adopt the PLKPlaidLinkViewDelegate protocol

COPY

COPIED!

In the LinkDemo applications this is handled by the main view controller object.

extension ViewController : PLKPlaidLinkViewDelegate
@interface ViewController (PLKPlaidLinkViewDelegate) <PLKPlaidLinkViewDelegate>
@end

Implement the delegate methods

COPY

COPIED!

The PLKPlaidLinkViewDelegate methods are the main communication back channel to your application for Plaid Link for iOS.

onSuccess

This delegate method is called when the user successfully linked their bank account with Plaid. Use this to upload and store the publicToken with your service for use with the Plaid API.

func linkViewController(_ linkViewController: PLKPlaidLinkViewController, didSucceedWithPublicToken publicToken: String, metadata: [String : Any]?) {
    dismiss(animated: true) {
        // Handle success, e.g. by storing publicToken with your service
        NSLog("Successfully linked account!\npublicToken: \(publicToken)\nmetadata: \(metadata ?? [:])")
        self.handleSuccessWithToken(publicToken, metadata: metadata)
    }
}
- (void)linkViewController:(PLKPlaidLinkViewController*)linkViewController
 didSucceedWithPublicToken:(NSString*)publicToken
                  metadata:(NSDictionary<NSString*,id>* _Nullable)metadata {
    [self dismissViewControllerAnimated:YES completion:^{
        // Handle success, e.g. by storing publicToken with your service
        NSLog(@"Successfully linked account!\npublicToken: %@\nmetadata: %@", publicToken, metadata);
        [self handleSuccessWithToken:publicToken metadata:metadata];
    }];
}

onExit

This delegate method is called when the user exited from Plaid Link or when an error occurred. In case of an error you may want to display error related information to user and have them retry linking their account.

func linkViewController(_ linkViewController: PLKPlaidLinkViewController, didExitWithError error: Error?, metadata: [String : Any]?) {
    dismiss(animated: true) {
        if let error = error {
            NSLog("Failed to link account due to: \(error.localizedDescription)\nmetadata: \(metadata ?? [:])")
            self.handleError(error, metadata: metadata)
        }
        else {
            NSLog("Plaid link exited with metadata: \(metadata ?? [:])")
            self.handleExitWithMetadata(metadata)
        }
    }
}
- (void)linkViewController:(PLKPlaidLinkViewController*)linkViewController
          didExitWithError:(NSError* _Nullable)error
                  metadata:(NSDictionary<NSString*,id>* _Nullable)metadata {
    [self dismissViewControllerAnimated:YES completion:^{
        if (error) {
            NSLog(@"Failed to link account due to: %@\nmetadata: %@", [error localizedDescription], metadata);
            [self handleError:error metadata:metadata];
        }
        else {
            NSLog(@"Plaid link exited with metadata: %@", metadata);
            [self handleExitWithMetadata:metadata];
        }
    }];
}

onEvent

This optional delegate method is called when certain events in the Plaid Link flow have occurred, for example when the user selected an instutition. This enables your application to gain further insight into what is going on as the user goes through the Plaid Link flow. For details about the events see the link-web onEvent documentation.

func linkViewController(_ linkViewController: PLKPlaidLinkViewController, didHandleEvent event: String, metadata: [String : Any]?) {
    NSLog("Link event: \(event)\nmetadata: \(metadata ?? [:])")
}
- (void)linkViewController:(PLKPlaidLinkViewController*)linkViewController
            didHandleEvent:(NSString*)event
                  metadata:(NSDictionary<NSString*,id>* _Nullable)metadata {
    NSLog(@"Link event: %@\nmetadata: %@", event, metadata);
}

The metadata contains the following keys, note that values can be [NSNull null].

Constant Description
kPLKMetadataAccountIdKey
String
Identifier for the selected account
kPLKMetadataAccountKey
Dictionary
Contains the keys kPLKMetadataIdKey and kPLKMetadataNameKey. Only applicable when the selectAccount property is set to true
kPLKMetadataIdKey
String
Identifier for the selected account
kPLKMetadataNameKey
String
Name of the institution or selected account
kPLKMetadataInstitutionKey
Dictionary
Contains the keys kPLKMetadataNameKey and kPLKMetadataInstitutionTypeKey
kPLKMetadataInstitutionTypeKey
String
An internal identifier for the institution
kPLKMetadataStatusKey
String
Indicates the point at which the user exited the Link flow (see explanation of possible values).
kPLKMetadataRequestIdKey
String
An internal identifier that helps us track your request in our system, please include it in every support request
kPLKMetadataPlaidApiRequestIdKey
String
An internal identifier that helps us track your request in our system, please include it in every support request

In addition to the above the metadata contains the following keys for onEvent delegate method, note that values can be [NSNull null].

Constant Description
kPLKMetadataInstitutionSearchQueryKey
String
The query used to search for institutions.
kPLKMetadataInstitutionIdKey
String
The ID of the selected [institution][institutions].
kPLKMetadataInstitutionNameKey
String
The name of the selected [institution][institutions].
kPLKMetadataLinkRequestIdKey
String
The request ID for the last request made by Link. This can be shared with Plaid Support to expedite investigation.
kPLKMetadataLinkSessionIdKey
String
The link_session_id is a unique identifier for a single session of Link. It is always available and will stay constant throughout the flow.
kPLKMetadataErrorTypeKey
String
The error type that the user encountered.
kPLKMetadataErrorCodeKey
String
The error code that the user encountered.
kPLKMetadataErrorMessageKey
String
The error message that the user encountered.
kPLKMetadataMFATypeKey
String
If set, the user has encountered one of the following MFA types: code, device, questions, selections.
kPLKMetadataViewNameKey
String
The name of the view that is being transitioned to.
kPLKMetadataTimestampKey
String
An ISO 8601 representation of when the event occurred.
kPLKMetadataExitStatusKey
String
The status key indicates the point at which the user exited the Link flow.

Possible values for the kPLKMetadataStatusKey metadata:

Constant Description
kPLKStatusConnected User completed the Link flow
kPLKStatusRequiresQuestions User prompted to answer security question(s)
kPLKStatusRequiresSelections User prompted to answer multiple choice question(s)
kPLKStatusRequiresCode User prompted to provide a one-time passcode.
kPLKStatusChooseDevice User prompted to select a device at which to receive a one-time passcode.
kPLKStatusRequiresCredentials User prompted to provide credentials for the selected financial institution or has not yet selected a financial institution
kPLKStatusRequiresRecaptcha User prompted to verify they are human via reCAPTCHA
kPLKStatusInstitutionNotFound User exited the Link flow after unsuccessfully (no results returned) searching for a financial institution

Presentation

Presenting PLKPlaidLinkViewController

Starting the Plaid Link for iOS experience is as simple as creating and presenting an instance of PLKPlaidLinkViewController.

// With shared configuration from Info.plist
let linkViewDelegate = self
let linkViewController = PLKPlaidLinkViewController(delegate: linkViewDelegate)
if (UI_USER_INTERFACE_IDIOM() == .pad) {
    linkViewController.modalPresentationStyle = .formSheet;
}
present(linkViewController, animated: true)
// With shared configuration from Info.plist
id<PLKPlaidLinkViewDelegate> linkViewDelegate  = self;
PLKPlaidLinkViewController* linkViewController = [[PLKPlaidLinkViewController alloc] initWithDelegate:linkViewDelegate];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    linkViewController.modalPresentationStyle = UIModalPresentationFormSheet;
}
[self presentViewController:linkViewController animated:YES completion:nil];

When you would like to have more control over the configuration during runtime you can create an instance of PLKConfiguration and pass that during the initialization of the PLKPlaidLinkViewController.

// With custom configuration
let linkConfiguration = PLKConfiguration(key: "<#YOUR_PLAID_PUBLIC_KEY#>", env: .sandbox, product: .auth)
linkConfiguration.clientName = "Link Demo"
let linkViewDelegate = self
let linkViewController = PLKPlaidLinkViewController(configuration: linkConfiguration, delegate: linkViewDelegate)
if (UI_USER_INTERFACE_IDIOM() == .pad) {
    linkViewController.modalPresentationStyle = .formSheet;
}
present(linkViewController, animated: true)
// With custom configuration
PLKConfiguration* linkConfiguration;
@try {
    linkConfiguration = [[PLKConfiguration alloc] initWithKey:@"<#YOUR_PLAID_PUBLIC_KEY#>" env:PLKEnvironmentSandbox product:PLKProductAuth];
    linkConfiguration.clientName = @"Link Demo";
    id<PLKPlaidLinkViewDelegate> linkViewDelegate  = self;
    PLKPlaidLinkViewController* linkViewController = [[PLKPlaidLinkViewController alloc] initWithConfiguration:linkConfiguration delegate:linkViewDelegate];
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        linkViewController.modalPresentationStyle = UIModalPresentationFormSheet;
    }
    [self presentViewController:linkViewController animated:YES completion:nil];
} @catch (NSException *exception) {
    NSLog(@"Invalid configuration: %@", exception);
}
Update Mode

To initiate the update mode instantiate the PLKPlaidLinkViewController using initWithPublicToken:delegate: and pass your generated public_token as the first parameter. Then present the linkViewController instance as usual.

let linkViewDelegate = self
let linkViewController = PLKPlaidLinkViewController(publicToken: "<#GENERATED_PUBLIC_TOKEN#>", delegate: linkViewDelegate)
if (UI_USER_INTERFACE_IDIOM() == .pad) {
    linkViewController.modalPresentationStyle = .formSheet;
}
present(linkViewController, animated: true)
id<PLKPlaidLinkViewDelegate> linkViewDelegate  = self;
PLKPlaidLinkViewController* linkViewController = [[PLKPlaidLinkViewController alloc] initWithPublicToken:@"<#GENERATED_PUBLIC_TOKEN#>" delegate:linkViewDelegate];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    linkViewController.modalPresentationStyle = UIModalPresentationFormSheet;
}
[self presentViewController:linkViewController animated:YES completion:nil];

Customization

The preferred and recommended method to customize LinkKit is to use customization feature in the dashboard, Plaid Link for iOS will automatically use the values you provide there.

Troubleshooting

When things work differently as expected LinkKit will use the value of the PLKPLAIDLINK_DIAGNOSTICS environment variable and enable different logging to the console. Supported values for PLKPLAIDLINK_DIAGNOSTICS and their corresponding log level are:

Value Loglevel
0 None
1 Error
2 Info
3 Debug

Environment Variables can be added in the Arguments tab of the Run phase in the Scheme Editor (Product ► Scheme ► Edit Scheme ⌘<).

Edit Scheme Troubleshooting

Moving Forward

Migrating to production

COPY

COPIED!

Keep building your integration out in our Sandbox and Development API environments. When youʼre ready to go to Production, request access from the Dashboard. While you’re at it, be sure to also take a look at our Privacy Policy.

Getting help

COPY

COPIED!

Find answers to common integration and product questions at our Help Center. You can find all the code for this guide, including runnable sample applications, on GitHub.

Weʼre excited to see what you build!