iOS

Learn how to get started with Truv for your iOS application

Setup for iOS

Once you have your API keys, it's time to run the Truv iOS Quickstart app locally.
Requirements: XCode and Simulator

  1. git clone <https://github.com/truvhq/quickstart-ios>
  2. cd quickstart-ios
  3. Create a truv-quickstart/Constants.swift file with the following content (values with <> should be replaced by the proper keys or values):
import Foundation

var TruvClientID = "<client_id>"
var TruvClientSecret = "<access_key>"
var TruvAPIUrl = "https://prod.truv.com/v1/"
var TruvProductType = "<employment or income>"
  1. Open the project in XCode and run the app

Run Quickstart

The iOS Quickstart app emulates the experience of an applicant going through an employment and income verification.

After opening the Quickstart app you will be presented with the Truv Bridge.

Use the Sandbox credentials to successfully connect a payroll account.

When you click "Done" at the end of Bridge you will be able to see the data returned by the Truv.

Step-by-step overview

This flow involves a user, the application front end, the application back end and the TruvI. You can see a visual diagram of tokens and data exchange in Bridge section of docs.

1. Authorize and initialize Bridge

Your app sends an API request to Truv for bridge_token.

truv.getBridgeToken() { bridgeToken, error in
func getBridgeToken (completionHandler:@escaping (String?, Error?) -> Void ) -> URLSessionTask {
    let url = URL(string: "\(TruvAPIUrl)bridge-tokens/")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue(TruvClientID, forHTTPHeaderField: "X-Access-Client-Id")
    request.setValue(TruvClientSecret, forHTTPHeaderField: "X-Access-Secret")
        
    let task = URLSession.shared.dataTask(with: request) { data, response, error -> Void in
      guard let data = data, error == nil else {
        print(error?.localizedDescription ?? "No data")
        completionHandler(nil, error)
        return
      }
    
      do {
        let decoder = JSONDecoder()
        let decodedData = try decoder.decode(BridgeTokenResponse.self, from: data)
        completionHandler(decodedData.bridge_token, nil)
        return
      } catch {
        print("Something went wrong")
        completionHandler(nil, error)
        return
      }
    }
    task.resume()
    return task
  }

Your app loads a mobile page from Truv's CDN with bridge_token into native WebView.

let uuid = NSUUID().uuidString
  var components = URLComponents(string: "https://cdn.truv.com/mobile.html")
  components?.queryItems = [URLQueryItem(name: "bridge_token", value: bridgeToken)]
  let myRequest = URLRequest(url: (components?.url)!)
  self.webView.load(myRequest)

2. User connects account

The user selects an employer, choses their provider, logs in, and clicks Done. public_token is generated.

let publicToken = (payload?["public_token"] as! String)
  truv.getAccessToken(publicToken: publicToken) { accessToken, error in
    if(TruvProductType == "employment") {
      self.setupEmployment(accessToken: accessToken!)
    } else {
      self.setupIncome(accessToken: accessToken!)
    }
  }

Your backend sends an API request to Truv exchanging the temporary token for the access_token.

func getAccessToken (publicToken: String, completionHandler:@escaping (String?, Error?) -> Void ) -> URLSessionTask {
    let url = URL(string: "\(TruvAPIUrl)access-tokens/")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue(TruvClientID, forHTTPHeaderField: "X-Access-Client-Id")
    request.setValue(TruvClientSecret, forHTTPHeaderField: "X-Access-Secret")
    let json: [String: Any] = ["public_tokens": [publicToken]]
    do {
      let jsonData = try JSONSerialization.data(withJSONObject: json)
      request.httpBody = jsonData
    } catch {
      print("Access Token Error")
      print(error)
      completionHandler(nil, error)
    }
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error -> Void in
      guard let data = data, error == nil else {
          print(error?.localizedDescription ?? "No data")
          completionHandler(nil, error)
          return
      }
      do {
        let decoder = JSONDecoder()
        let decodedData = try decoder.decode(AccessTokenResponse.self, from: data)
        completionHandler(decodedData.access_tokens.first, nil)
      } catch {
        print("Something went wrong")
        print(error)
        completionHandler(nil, error)
      }
    }
    task.resume()
    return task
  }

3. Get data from API

Your backend sends an API request to Truv with the access_token for employment/income verification.

func getEmploymentInfoByToken (accessToken: String, completionHandler:@escaping ([String: Any]?, Error?) -> Void ) -> URLSessionTask {
    let url = URL(string: "\(TruvAPIUrl)verifications/employments/")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue(TruvClientID, forHTTPHeaderField: "X-Access-Client-Id")
    request.setValue(TruvClientSecret, forHTTPHeaderField: "X-Access-Secret")
    let json: [String: Any] = ["access_token": accessToken]
    do {
      let jsonData = try JSONSerialization.data(withJSONObject: json)
      request.httpBody = jsonData
    } catch {
      print("Employment Info by Token Error")
      print(error)
      completionHandler(nil, error)
    }
        
    let task = URLSession.shared.dataTask(with: request) { data, response, error -> Void in
      guard let data = data, error == nil else {
        print(error?.localizedDescription ?? "No data")
        completionHandler(nil, error)
        return
      }
      let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
      completionHandler(json, nil)
    }
    task.resume()
    return task
    }

Your app renders the data sent back by Truv for the user.

let finalView = EmploymentView(data: result!)
                    
  self.webView.removeFromSuperview()
  self.view.addSubview(finalView)