Changelog

Connect Layer - iOS Example

Introduction

Connect Layer provides a client-side functionality that allows you to authenticate users with their bank and retrieve accessCode required to obtain the user’s permanent token.
This guide shows you how to integrate Dapi connect layer into an Android application via a web view.

Basic Setup

In your iOS project, start by importing WebKit

import WebKit

Your class should conform to the WKNavigationDelegate

class ViewController: UIViewController, WKNavigationDelegate {

Create a web view object inside your class

private lazy var webView: WKWebView = {
   let webView = WKWebView()
    webView.navigationDelegate = self
    webView.allowsBackForwardNavigationGestures = false
    webView.scrollView.bounces = false
    webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)
    webView.translatesAutoresizingMaskIntoConstraints = false
    let url = self.generateConnectURL()
    let request = URLRequest(url: url)
    webView.load(request)
   return webView
}()

The generateConnectURL() method generates a URL containing your app key, environment, and other keys let you control the connect layer.

private func generateConnectURL() -> URL {
    let configs = [
        "appKey" : "INSERT_YOUR_APP_KEY_HERE",
        "isMobile" : "false",
        "isWebview" : "true",
        "countries" : stringCountries(["AE"]),
        "environment" : "sandbox",
        "showLogo" : "true"
    ]
    
    var components = URLComponents()
    components.scheme = "https"
    components.host = "connect.dapi.co"
    components.path = "/v3/connection"
    
    var queryItems: [URLQueryItem] = []
    configs.forEach { element in
        queryItems.append(.init(name: element.key, value: element.value))
    }
    
    components.queryItems = queryItems
    
    return components.url!
}

func stringCountries(_ countries: [String]) -> String {
  if countries.count > 0 {
    let joinedElements = countries.joined(separator: "\",\"")

    let output = "[\"\(joinedElements)\"]"

    return output
  } else {
    return "[]"
  }
}

Currently, we open a web page inside a web view. We need to listen to URL changes. Hence, we observe the value "URL". When your user connects their account, fails to connect, or exits the web view, Dapi redirects to other web pages. Observing the URL changes allows us to know the status of connecting an account.

Observe URL changes.

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if change?[.newKey] == nil {
        // we're not interseted in this change.
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
    } else {
        if let url = self.webView.url {
            handleURLChange(url)
        }
    }
}

Implement the URL change handler

private func handleURLChange(_ url: URL) {
    let items = URLComponents.init(string: url.absoluteString)?.queryItems
    let result = url.lastPathComponent
    if result == "link" {
        print("Banks list loaded")
    } else if result == "success" {
        print("Connected successfully")
        // items will contain needed parameters such as userID, etc.
        items?.forEach({ item in
            print("\(item.name): \(item.value ?? "")")
        })
       // Store the items, and use them next to call Dapi APIs.
       // i.e. exchange token, get accounts, etc.
    } else if result == "error" {
        print("Failed to connect")
        // items will contain error and failure reason
        items?.forEach({ item in
            print("\(item.name): \(item.value ?? "")")
        })
        //use the items to show the error to the user
    } else if result == "exit" {
        print("Existing")
        self.webView.isHidden = true
    }
}

In every URL change the web page makes, it lets us know the parameters of the action via the query items.
For example, the "link" action means your user has authenticated successfully. To know the parameters, we use queryItems which will contain a list of variables you need to make API calls to Dapi.

You need to store the values of the query items to call Dapi APIs subsequently. You will require accessCode, userSecret and connectionID when calling Exchange Token in order to obtain a permanent accessToken for the user. Or you will require the same values when calling an exchange token function in any of the Server Side Libraries .

userSecret value will be required as a parameter in all of the following Data and Payment API calls.