Using the Reference Application

HYPR SDK for iOS

General Setup

All general SDK setup is handled in the AppDelegate.swift class. As an SDK consumer, you can perform the following operations:

  • Enable authenticators
  • Set a push notifications provider
  • Set a custom headers delegate
  • Enable SSL pinning (recommended, but also should be enabled on server)
  • Enable the AAID picker view controller

In the reference app project in the AppDelegate.swift class, you can also check UI customization and other optional functionality.

internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Enable the authenticators
        HYPRUAFClient.registerAuthenticatorModule(HYPRFingerprintAsm.self)
        HYPRUAFClient.registerAuthenticatorModule(HYPRFaceIDAsm.self)
        HYPRUAFClient.registerAuthenticatorModule(HYPRFaceAsm.self)
        HYPRUAFClient.registerAuthenticatorModule(HYPRPINAsm.self)
        
        HYPRUserAgent.initializeHYPRADP { (error) in
            if error != nil {
                print("ADP init error: \(error!)")
            }
        }
        
        // Out of Band Authentication - Set the Push Notification Adapter (FirebaseAdapter by default)
        HYPRUserAgent.setNotificationProviderAdapter(HYPRFirebaseAdapter.shared())
        // Out of Band Authentication - Enable Push Notifications
        HYPRFirebaseAdapter.shared().userPushNotifications(enabled: true)
        
        // For sending/receiving HTTP Headers in HYPR SDK calls
        HYPRUserAgent.setCustomHeadersDelegate(self)
        
        // Enable or Disable SSL Pinning
        HYPRUserAgent.setSSLPinningEnabled(false)
        
        // Enable default AAID Picker UI for UserAgent
        HYPRUserAgent.setAAIDPickerViewEnabled(true)
        
        // Set AAIDPickerViewController
        let viewController = UIStoryboard(name:"Main", bundle: nil).instantiateViewController(withIdentifier: "PickerViewController")
        HYPRUserAgent.setAAIDPickerViewController(viewController)
        
        // Optional: Set the Face Authenticator Parameters
        HYPRFaceAsm.setTimeout(60000)
        
        return true
    }

Setting UserAgent Profiles

There are three view controllers:

  • ViewController.swift to demonstrate FIDO-only use case, registration, and authentication
  • WebProfileViewController.swift to demonstrate pairing and subsequent login with a web-based account
  • WorkstationProfileViewController.swift to demonstrate pairing, unlock, and offline unlock with a workstation

They all have a similar setProfile method. Here you must specify the rpAppId (which corresponds to the desired rpAppId in Control Center) and the relying party server URL.

private func setProfile() {
        // Retrieve personaID. This value is unique per profile
        let localPersonaId = UserDefaults.standard.value(forKey: WorkstationProfileViewController.wokrstationKey) as! String?
            
        // Find the profile by personaID if it exists
        let filteredProfiles = HYPRUserAgent.sharedInstance().profiles()?.filter({ (profile) -> Bool in
            profile.persona?.personaId == localPersonaId
        })
        
        if localPersonaId != nil && filteredProfiles != nil && filteredProfiles!.count > 0 {
            HYPRUserAgent.sharedInstance().switchActiveProfile(filteredProfiles![0])
        // Otherwise create and register new profile
        } else  {
            // Set the Authenticator UI Customizations
            setAuthenticatorUICustomizations()
            
            // Create the profile configuration where you specify the following:
            let profileConfig = HYPRUserAgentProfileConfiguration(rpAppId: "RP App ID here: i.e. HYPRDefaultApplication",
                                                           rpServerUrl: "Place the RP URL here: i.e. https://9999-pov.hypr.com",
                                                           deviceType: "WORKSTATION",
                                                           rpSSLPinCredentials: nil,
                                                           additionalData: nil)

            // Create the profile with the profile configuration
            let profile = HYPRUserAgentProfile(displayName: "<Your profile name goes here>", configuration: profileConfig, persona: nil, userAccounts: nil, apiEndpoints: nil)
            // Register it
            HYPRUserAgent.sharedInstance().registerProfile(profile!)
            if let personaId = HYPRUserAgent.sharedInstance().activeProfile()?.persona?.personaId {
                UserDefaults.standard.set(personaId, forKey: WorkstationProfileViewController.wokrstationKey)
            }      
        }
    }

Setting ActionId

To register/authenticate using a specific FIDO policy, you may specify each as an ActionID. Passing nil will call the default policy if one exists at your rpAppId.

To register/authenticate in ViewController.swift you must substitute your policy names for <Your policy name goes here> for both registration and authentication.

@IBAction func registerNewUser(_ sender: UIButton) {
        HYPRUserAgent.setDefaultAPIVersion(NSNumber(integerLiteral: 2))
        guard HYPRUserAgent.sharedInstance().activeUserAccount() == nil else {
            presentStatusAlert(title: "Registration", message: "You already registered a user either from Out of Band Device Setup or standard Registration")
            return;
        }
        HYPRUserAgent.setParentViewController(self)
        HYPRUserAgent.sharedInstance().registerUser(withName: nil, action: "<Your policy name goes here>", completion: { (error) in
            if (error != nil) {
                self.presentStatusAlert(title: "Registration", message: "There was an error registering the user: \(error?.localizedDescription ?? "")")
            } else {
                self.presentStatusAlert(title: "Registration", message: "User was successfully registered!")
            }
        })
    }
    
    @IBAction func authenticate(_ sender: UIButton) {
        HYPRUserAgent.setDefaultAPIVersion(NSNumber(integerLiteral: 2))
        HYPRUserAgent.setParentViewController(self)
        HYPRUserAgent.sharedInstance().authenticateUser(nil, action: "<Your policy name goes here>", completion: { (error) in
            if(error != nil) {
                // Proces the authentication error:
                self.presentStatusAlert(title: "Authentication", message: "There was an error authenticating the user \(error?.localizedDescription ?? "")")
            }
            else {
                self.presentStatusAlert(title: "Authentication", message: "User was successfully authenticated!")
            }
        })
    }

In WebProfileViewController.swift you can register your workstation with a QR or with a PIN. Using a PIN you can specify the policy name as ActionID instead of <Your policy goes here>. If nil is passed the default registration action will be used.

@IBAction func addWebAccountQR(_ sender: Any) {
        // // Uses information from QR Code to register the remote device
        HYPRUserAgent.sharedInstance().registerRemoteDevice { (error) in
            if(error != nil) {
                self.presentInfoAlert(title: "Error", message: "OOB Device Setup Failed: \(error?.localizedDescription ?? "")")
            }
            else {
                self.presentInfoAlert(title: "Success", message: "OOB Device Setup was successful")
                self.tableView.reloadData()
            }
        }
    }

// Works with v3 api only
    @IBAction func addWebAccountPIN(_ sender: Any) {
        let userAccount = HYPRUserAgent.sharedInstance().activeUserAccount()
        // if no userAccount exists and nil is passed as a userAccount parameter - the new userAccount will be created
        // if pass nil to actionId parameter - the default policy will be used
        HYPRUserAgent.sharedInstance().registerRemoteDevice(forUser: userAccount ?? nil, pinInputType: .alert, actionId: "<Your policy goes here>") { (error) in
            if(error != nil) {
                self.presentInfoAlert(title: "Error", message: "OOB Device Setup Failed: \(error?.localizedDescription ?? "")")
            }
            else {
                self.presentInfoAlert(title: "Success", message: "OOB Device Setup was successful")
                self.tableView.reloadData()
            }
        }

    }

In WebProfileViewController.swift you can register your workstation with a QR or with a PIN. Using a PIN you can specify the policy name as ActionID instead of <Your policy goes here>. If nil is passed the default registration action will be used.

// If you are using this method, you don't need to setup the profile as descibed in setProfile() method
    @IBAction func addWorkstationQR(_ sender: Any) {
        // Uses information from QR Code to register the remote device
        HYPRUserAgent.sharedInstance().registerRemoteDevice { (error) in
            if(error != nil) {
                self.presentInfoAlert(title: "Error", message: "OOB Device Setup Failed: \(error?.localizedDescription ?? "")")
            }
            else {
                self.presentInfoAlert(title: "Success", message: "OOB Device Setup was successful")
                self.tableView.reloadData()
            }
        }
    }
    
    // Works with v3 api only
    @IBAction func addWorkstationPIN(_ sender: Any) {
        let userAccount = HYPRUserAgent.sharedInstance().activeUserAccount()
        // if no userAccount exists and nil is passed as a userAccount parameter - the new userAccount will be created
        // if pass nil to actionId parameter - the default policy will be used
        HYPRUserAgent.sharedInstance().registerRemoteDevice(forUser: userAccount ?? nil, pinInputType: .alert, actionId: "<Your policy goes here>") { (error) in
            if(error != nil) {
                self.presentInfoAlert(title: "Error", message: "OOB Device Setup Failed: \(error?.localizedDescription ?? "")")
            }
            else {
                self.presentInfoAlert(title: "Success", message: "OOB Device Setup was successful")
                self.tableView.reloadData()
            }
        }
    }

🚧

Accept No Imitations

The web-based flow does not work on a simulator.

The above settings are the main settings of the HYPR SDK for iOS. Other optional settings can be found in the reference app classes.

App Screens

  • FIDO-only flow:
1242
  • Workstation flow:
1242
  • Web flow:
1242