Device Fingerprinting - iOS Integration

This page describes how to add the Threatmetrix SDK to your iOS project.

Visit the Downloads page to download the most up to date version of the Device Fingerprinting files for your platform.

Once you have added the ThreatMetrix files to your project, your application will automatically generate a device fingerprint during initialization.

Integration

The sections below describe how to add the ThreatMetrix modules to your iOS project. The Overview section describes the process and defines the files you will need to include. The Guide section provides step-by-step instructions for adding the modules to your project and ensuring that your application has the required settings.

Overview

Integrating Device Fingerprinting into your application requires creating new modules for the following files that are provided by Threatmetrix:

  • TMXProfilingConnections.dmg - Handles transferring data to and from the Threatmetrix backend.
  • TMXProfiling.dmg - Manages the generation of device profiles.

Guide

Follow the steps below to add the ThreatMetrix modules to your project:

  1. Save the ThreatMetrix modules to your local machine: TMXProfiling.dmg, and TMXProfilingConnections.dmg.

  2. Copy the following files to your application directory as shown in the image below: TMXProfiling.xcframework, and TMXProfilingConnections.xcframework. TMXBehavioralBiometrics is not required for this integration. Directories

  3. Open your application in Xcode.

  4. Select the “Project Navigator” panel in Xcode.

  5. Drag and drop the framework files from step 2 into your application.

  6. Select “Copy item if needed”.

  7. Make sure the correct target is selected in the “Add to targets” section as shown below: Targets

  8. Select the application target.

  9. Select the General tab.

  10. In the “Frameworks, Libraries and Embedded Content” section, make sure that the following files are added: TMXProfiling.xcframework, and TMXProfilingConnections.xcframework.

  11. Ensure that all files are included with the “Embed and Sign” setting, as described below:

    • Select the “Build Phases” tab.
    • Open the “Link Binary with Libraries” and “Embed Frameworks” sections and check that the ThreatMetrix files are listed, as shown in the image below. TMXBehavioralBiometrics is not required for this integration.

    Build

  12. Copy the code below and paste it into your project:

    //
    //  LemonBankProfileController.swift
    //  VestaCorporation
    //
    //  Created by Admin on 05/03/2018.
    //  Copyright © 2018 VestaCorporation. All rights reserved.
    //
        
    import Foundation
    import UIKit
    import TMXProfiling
    import TMXProfilingConnections
        
    class TrustDefender: NSObject {
        static let shared = TrustDefender()
            
        private var profile: TMXProfiling = TMXProfiling.sharedInstance()!
            
        private var sessionID: String = ""
        private var orgID: String = ""
        private var webSessionID: String = ""
        private var deviceName : String = ""
        private var deviceModel : String = ""
            
        private(set) var isProfileInitialized: Bool = false
            
        func configure(forDeviceName name: String, deviceModel: String, orgID: String, webSessionID: String) -> TrustDefender {
            self.deviceName = name
            self.deviceModel = deviceModel
            self.orgID = orgID
            self.webSessionID = webSessionID
                
            let profilingConnections = TMXProfilingConnections.init()
            profilingConnections.connectionRetryCount = 2
                
            //Configuration only fails due to programming error, therefore by using an assert here we make sure there is no error in our configuration object
            profile.configure(configData: [
                TMXOrgID: orgID,
                TMXFingerprintServer: "h.online-metrix.net",
                // (OPTIONAL) If Keychain Access sharing groups are used, specify like this
                TMXKeychainAccessGroup: "TEAMID.com.threatmetrix",
                TMXProfilingConnectionsInstance: profilingConnections
            ])
                
            return self
        }
            
        func configureForDefaultDeviceInformation(orgID: String, webSessionID: String) -> TrustDefender {
            if isProfileInitialized {
                return self
            }
                
            return configure(forDeviceName: UIDevice.current.name, deviceModel: UIDevice.current.model, orgID: orgID, webSessionID: webSessionID)
        }
            
        func doProfile() {
            if isProfileInitialized {
                return
            }
                
            print("Using TrustDefender framework \(profile.version())")
                
            // Fire off the profiling request.
            profile.profileDevice(profileOptions: [TMXCustomAttributes: [deviceName, deviceModel], TMXSessionID: webSessionID]) { (result) in
                guard let response = result as? [String: Any],
                    let sessionID = response[TMXSessionID] as? String,
                    let profileStatus = response[TMXProfileStatus] as? NSNumber,
                    let status = TMXStatusCode(rawValue: profileStatus.intValue) else {
                    print("THMTrustDefender profile wrong response")
                    return
                }
                    
                var statusString = ""
                self.sessionID = sessionID
                switch status {
                    case .ok:
                        statusString = "ok"
                        self.isProfileInitialized = true
                    case .networkTimeoutError: statusString = "Timed out"
                    case .connectionError: statusString = "Connection Error"
                    case .hostNotFoundError: statusString = "Host Not Found Error"
                    case .internalError: statusString = "Internal Error"
                    case .interruptedError: statusString = "Interrupted Error"
                    default: statusString = "Other reason"
                }
                    
                print("Profile completed with: \(statusString) and session ID: \(self.sessionID)")
            }
        }
    }