Orchestration SDKs

Integrating FIDO DaVinci flows into iOS apps

PingOne iOS

The FIDO module offers a streamlined API for handling FIDO interactions.

It abstracts away the complexities of the underlying FIDO protocols, allowing you to quickly add strong authentication to your applications.

Before you begin

To enable FIDO authentication in your app you must complete the following tasks:

Adding FIDO entitlements to an iOS app

  1. In Xcode, in the Project Navigator, double-click your application to open the Project pane.

  2. On the Signing & Capabilities tab, click Capability, type Associated Domains, and then double click the result to add the capability.

  3. In Domains, click the Add () button, and enter the following entries:

    1. webcredentials:, followed by the hostname where you uploaded the apple-app-site-association file earlier.

      For example, webcredentials:openam-docs.forgeblocks.com

      The result will resemble the following:

      ios fido capabilities journeys
      Figure 1. Configuring Advanced Identity Cloud entitlements in iOS.

Step 1. Installing modules

To install the FIDO module for iOS, use Swift Package Manager (SPM) or Cocoapods to add the dependency to your project.

  • SPM (Swift Package Manager)

  • CocoaPods

You can install packages by using SPM (Swift Package Manager) on the iOS project.

  1. In Xcode, in the Project Navigator, right-click your project, and then click Add Package Dependencies…​.

  2. In the Search or Enter Package URL field, enter the URL of the repo containing the Orchestration SDK for iOS, https://github.com/ForgeRock/ping-ios-sdk.git.

  3. In Add to Project, select the name of your project, and then click Add Package.

    Xcode shows a dialog containing the libraries available for iOS.

  4. Select the PingFido library, and in the Add to Target column select the name of your project.

  5. Repeat the previous step for any other packages you want to use in your project.

  6. Click Add Package.

    Xcode displays the chosen packages and any prerequisites they might have in the Package Dependencies pane of the Project Navigator.

  1. If you don’t already have CocoaPods, install the latest version.

  2. If you don’t already have a Podfile, in a terminal window, run the following command to create a new Podfile:

    pod init
  3. Add the following lines to your Podfile:

    pod 'PingFido'
  4. Run the following command to install pods:

    pod install

Step 2. Registering FIDO authenticators

To register a FIDO authenticator, use the register() function. The function returns either success or failure.

The Orchestration SDK provides classes for handling the FIDO registration requests, depending on the orchestration server you use:

  • FidoRegistrationCollector - PingOne DaVinci flows

  • FidoRegistrationCallback - Advanced Identity Cloud and PingAM authentication journeys

  • DaVinci flow

  • Advanced Identity Cloud and PingAM journey

Step 1. Handling FIDO callbacks in a DaVinci flow
ForEach(continueNode.collectors, id: \.id) { collector in
  switch collector {
    case let fidoRegistrationCollector as FidoRegistrationCollector:
      FidoRegistrationCollectorView(collector: fidoRegistrationCollector, onNext: { onNext(true) })
  }
}
Step 2. Calling register in FidoRegistrationCollectorView
Task {
    // 2. Get the window
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
          let window = windowScene.windows.first else {
        print("Could not find active window scene.")
        return // Exit if no window found
    }

    // 3. Call the async function and await its Result
    let result = await collector.register(window: window)

    // 4. Handle the Result
    switch result {
    case .success(let attestationValue):
        // Optional: Use attestationValue if needed
        print("FIDO Registration successful: \(attestationValue)")
        // Call onNext only on success
        onNext()
    case .failure(let error):
        // Handle errors
        print("FIDO Registration failed: \(error.localizedDescription)")
    }
}
Step 1. Handling FIDO callbacks in a Advanced Identity Cloud or PingAM journey
ForEach(Array(continueNode.callbacks.enumerated()), id: \.offset) { index, callback in
  switch callback {
    case let fidoRegistrationCallback as FidoRegistrationCallback:
      FidoRegistrationCallbackView(callback: fidoRegistrationCallback, onNext: onNext)
  }
}
Step 2. Calling register in FidoRegistrationCallbackView
Task {
    // Get the window
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
          let window = windowScene.windows.first else {
        print("Could not find active window scene.")
        return // Exit if no window found
    }

    // Call the async function and await its Result
    let result = await callback.register(window: window)

    // Handle the Result
    switch result {
    case .success(let attestationValue):
        // Optional: Use attestationValue if needed
        print("FIDO Registration successful: \(attestationValue)")
        // Call onNext
        onNext()
    case .failure(let error):
        // Handle errors
        print("FIDO Registration failed: \(error.localizedDescription)")
        // Call onNext
        onNext()
    }
}

Step 3. Authenticating using a FIDO authenticator

To authenticate using a registered FIDO authenticator, use the authenticate() function. The function returns either success or failure.

The Orchestration SDK provides classes for handling the FIDO authentication requests, depending on the orchestration server you use:

  • Fido2AuthenticationCollector - PingOne DaVinci flows

  • Fido2AuthenticationCallback - Advanced Identity Cloud and PingAM authentication journeys

  • DaVinci flow

  • Advanced Identity Cloud and PingAM journey

Step 1. Handling FIDO callbacks in a DaVinci flow
ForEach(continueNode.collectors, id: \.id) { collector in
  switch collector {
    case let fidoAuthenticationCollector as FidoAuthenticationCollector:
      FidoAuthenticationCollectorView(collector: fidoAuthenticationCollector, onNext: { onNext(true) })
  }
}
Step 2. Calling authenticate in FidoAuthenticationCollectorView
Task {
    // Get the window
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
          let window = windowScene.windows.first else {
        print("Could not find active window scene.")
        return // Exit if no window found
    }

    // Call the async function and await its Result
    let result = await authenticate.authenticate(window: window)

    // 4. Handle the Result
    switch result {
    case .success(let attestationValue):
        // Optional: Use attestationValue if needed
        print("FIDO Authentication successful: \(attestationValue)")
        // Call onNext only on success
        onNext()
    case .failure(let error):
        // Handle errors
        print("FIDO Authentication failed: \(error.localizedDescription)")
    }
}
Step 1. Handling FIDO callbacks in a Advanced Identity Cloud or PingAM journey
ForEach(Array(continueNode.callbacks.enumerated()), id: \.offset) { index, callback in
  switch callback {
    case let fidoAuthenticationCallback as FidoAuthenticationCallback:
      FidoAuthenticationCallbackView(callback: fidoAuthenticationCallback, onNext: onNext)
  }
}
Step 2. Calling authenticate in FidoAuthenticationCallbackView
Task {
    // Get the window
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
          let window = windowScene.windows.first else {
        print("Could not find active window scene.")
        return // Exit if no window found
    }

    // Call the async function and await its Result
    let result = await callback.authenticate(window: window)

    // Handle the Result
    switch result {
    case .success(let attestationValue):
        // Optional: Use attestationValue if needed
        print("FIDO Authentication successful: \(attestationValue)")
        // Call onNext
        onNext()
    case .failure(let error):
        // Handle errors
        print("FIDO Authentication failed: \(error.localizedDescription)")
        // Call onNext
        onNext()
    }
}