# Migrate to EncapSwiftAPI

# Overview

As Swift is moving along with ABI and Module stability, we want to provide an even better experience for developers that are using Swift. Our new API is more Swift-friendly, and it is easier to integrate and use.

You can find information below on how to migrate from the EncapAPI to the EncapSwiftAPI.

Note

The core operations are the same and will not require any changes when you migrate.

# Project Setup

You need to download EncapSwiftAPI.xcframework from our repository. The repository is gated, therefore you require login credentials to access it.

  1. Request your Nexus repository login credentials from us at support@signicat.com.

  2. Navigate to our repository and enter your Nexus repository login credentials. Browse for the correct version using the following links:

  3. Download EncapAPI.xcframework.

  4. Follow the steps in Configure your project. The dependencies are the same.

Note

Since this is a Swift framework, no bridging-header is required. The only step that is needed after linking the framework and adding dependencies is to import the API:

import EncapSwiftAPI

# Migration guide

The purpose of this guide is to highlight the differences with the new API, and to give an overview of what is required to start using it.

If you want to look through complete code examples for all of the operations, then you can use the example project.

# EncapConfig

Improved initialisation of the EncapConfig using the init with default parameters makes it easier to identify and set the minimum required configuration needed:

let encapConfig = EncapConfig(serverURL: "some value", applicationId: "some value", publicKey: "some value")

When migrating, EncapController.shared().config.applicationId = applicationId becomes → EncapController.shared.config.applicationId = applicationId.

# EncapController operations

All operations have an onCompletion block containing a Result(Apple Result doc (opens new window)) type, giving either .success or .failure.

The code block below shows an example from the loadConfig:

/// Get server configuration parameters before start of activation, this call is optional and not needed in client only mode.
///
/// - Parameter onCompletion: The block that gives Result containing .success or .failure
public func loadConfig(onCompletion: @escaping (Result<LoadConfigResult, ErrorResult>) -> ())

The code blocks below shows an example of migrating from the EncapAPI (Objective-C version) to the EncapSwiftAPI (Swift version) for cancelSession, in the example project.

Before:

EncapController.shared.cancelSession(onSuccess: {
        self.stopAnimate()
        self.setState(.stateActivated)
        self.statusText.text = "Cancelled session"
}, onError: { errorResult in
        self.stopAnimate()
        self.handleError(errorResult, in: .stateCancelSession)
})

After:

EncapController.shared.cancelSession(onCompletion: { result in
      self.stopAnimate()
      
      switch result {
          case .success(_):
              self.setState(.stateActivated)
              self.statusText.text = "Cancelled session"
      
          case .failure(let errorResult):
              self.handleError(errorResult, in: .stateCancelSession)
      }
})

The same pattern is applicable for all of the operations in EncapController. For a complete example covering all operations, you can refer to the example project.

EncapController.swift interface

/// EncapController is a state machine that handles all operations with the Encap server.
public class EncapController {

    /// - Returns: A shared instance of EncapController
    public static let shared: EncapSwiftAPI.EncapController

    /// Set and get  EncapConfig
    public var config: EncapSwiftAPI.EncapConfig

    /// Check whether this controller instance is currently communicating with the Encap server to handle an operation.
    ///
    /// - Returns:true if the operation is in progress, otherwise false.
    public var isOperationInProgress: Bool { get }

    /// Checks if activation data is present on the device.
    /// It will not perform a call to Encap Server to check status of current activation.
    ///
    /// - Returns: Result<Bool, ErrorResult>  containing a Bool or ErrorResult if an unexpected error occurs during check.
    ///
    /// - Note: If the operation fails with EncapStorageUnavailable, you could try one extra call to this method before reactivating since the cause might be that the OS had not unlocked the Keychain yet (more likely on registrations activated on SDK version 3.5 and earlier).
    public func isActivatedLocally() -> Result<Bool, EncapSwiftAPI.ErrorResult>

    /// Checks if activation data is present on the device and returns activated authentication methods.
    /// It will not perform a check against Encap Server to check status of current activation.
    ///
    /// - Returns: Activated authentication methods, nil if not activated.
    public var activatedAuthenticationMethods: Set<EncapSwiftAPI.AuthMethod> { get }

    /// Version of Encap API.
    public var encapAPIVersion: String { get }

    /// Unique identifier for device, UUID stored in Keychain.
    public var uniqueIdentifier: String { get }

    /// Registration ID.
    public var registrationId: String? { get }

    /// Enabled Risk parameters in server config. The values will be available after a successful startActivation operation,
    /// and updated after a successful startActivation or startAuthentication operation if configuration of these values has changed.
    public var riskparameterServerConfig: EncapSwiftAPI.RiskParameterServerConfig { get }

    /// EncapController can be initialised with a name in order to support multiple active registrations in one application.
    ///
    /// - Note: If the application only supports one registration, the sharedController can be used.
    ///
    /// - Parameter name: The unique identifier chosen by the developer for a given registration.
    public init(name: String)

    /// Get server configuration parameters before start of activation, this call is optional and not needed in client-only mode.
    ///
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func loadConfig(onCompletion: @escaping (Result<EncapSwiftAPI.LoadConfigResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Start activation by creating an activation session with the activation code.
    ///
    /// - Parameter withCode: The application session's activation code shown to the end-user via the application. This can be nil when doing client-only activation, if enabled on the server.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func startActivation(withCode: String?, onCompletion: @escaping (Result<EncapSwiftAPI.StartActivationResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Activate the end-user from the earlier created registration session.
    ///
    /// - Parameter withAuthMethod: The Authentication method to activate. EncapAuthMethodDevice is always activated.
    /// - Parameter tokenPurpose: Optional - when provided this operation will yield a EncapToken that can be used to authorise tokenised operations.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    /// - Note If previously activated, this operation will deactivate the old registration data when started with valid parameters.
    public func finishActivation(withAuthMethod: EncapSwiftAPI.AuthMethod, tokenPurpose: EncapSwiftAPI.TokenPurpose = .none, onCompletion: @escaping (Result<EncapSwiftAPI.FinishActivationResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Initiating adding (activating) of a new, or update activated authentication method.
    ///
    /// - Parameter clientData: Base64 encoded client data to be returned as a SAML attribute, or nil if no client data.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func startAddOrUpdate(clientData: String? = nil, onCompletion: @escaping (Result<EncapSwiftAPI.StartAddOrUpdateResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Complete activation or update of authentication method from the earlier created session (StartAddOrUpdate).
    ///
    /// - Parameter authMethodToActivate: The Authentication method to activate or update. EncapAuthMethodDevice is always activated and cannot be updated.
    /// - Parameter authMethodToAuthenticate: Existing authentication method to authorise the add or update operation.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func finishAddOrUpdate(authMethodToActivate: EncapSwiftAPI.AuthMethod, authMethodToAuthenticate: EncapSwiftAPI.AuthMethod, onCompletion: @escaping (Result<EncapSwiftAPI.FinishAddOrUpdateResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Create a new authentication session by identifying ourselves.
    ///
    /// - Parameter clientOnly: Whether the authentication should be used by the client only (true) or used to authenticate an (existing) application session (false).
    /// - Parameter clientData: Base64 encoded client data to be returned in contextContent in startResult with MIME type application/x-encap-client-data, and in finishResult as a SAML attribute, or nil if no client data.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func startAuthentication(clientOnly: Bool, clientData: String? = nil, onCompletion: @escaping (Result<EncapSwiftAPI.StartAuthenticationResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Authenticate the end-user on the earlier created authentication session.
    ///
    /// - Parameter withAuthMethod: The authentication method  used for this authentication.
    /// - Parameter tokenPurpose: Optional - when provided this operation will yield an EncapToken that can be used to authorise tokenised operations.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func finishAuthentication(withAuthMethod: EncapSwiftAPI.AuthMethod, tokenPurpose: EncapSwiftAPI.TokenPurpose = .none, onCompletion: @escaping (Result<EncapSwiftAPI.FinishAuthenticationResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Cancel current activation or authentication session on server.
    ///
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func cancelSession(onCompletion: @escaping (Result<(), EncapSwiftAPI.ErrorResult>) -> ())

    /// Deactivate an authentication method.
    /// - Parameter authMethod: Authentication method to be deactivated.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func deactivate(authMethod: EncapSwiftAPI.AuthMethod, onCompletion: @escaping (Result<(), EncapSwiftAPI.ErrorResult>) -> ())

    /// Deactivate the registration. This causes any information on the device registration to be removed from the client and Encap server.
    /// The client will need to reactivate before continuing to use Encap.
    ///
    /// - Parameter onlyLocally: if true, only remove registration data on device. If false, a device authentication will be performed and registration will
    /// be removed on encap server, if device authentication is successful local registration data will be
    /// removed as well, if device authentication fails an error is returned (local registration data not removed).
    ///
    /// - Attention: onlyLocally is available to cover situations where the device authentication against Encap server
    /// fails and app developer/end-user still wants to wipe registration locally. Example: Device has no internet
    /// connection, first call (with onlyLocally = false) fails, app can now choose to call deactivate with
    /// onlyLocally = true directly or prompt end-user for input (try another time, wipe locally, cancel).
    ///
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func deactivate(onlyLocally: Bool, onCompletion: @escaping (Result<(), EncapSwiftAPI.ErrorResult>) -> ())

    /// Start offline authentication, using verification data received from server, as response to a start offline authentication request REST call.
    ///
    /// - Parameter verificationData: Containing challenge and context to be presented to end-user for the authentication.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func startOfflineAuthentication(verificationData: String, onCompletion: @escaping (Result<EncapSwiftAPI.StartOfflineAuthenticationResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Finish offline authentication with the given authentication parameter. This will generate an OTP (One Time Password) that the server can verify in a finish offline authentication request REST call.
    ///
    /// - Parameter withAuthMethod: The authentication method  used for this authentication.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func finishOfflineAuthentication(withAuthMethod: EncapSwiftAPI.AuthMethod, onCompletion: @escaping (Result<EncapSwiftAPI.FinishOfflineAuthenticationResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Set value for a risk parameter.
    /// If not set, the risk parameter won't be forwarded to Encap server.
    /// The value will persist (and forwarded to server) during the lifetime of the same EncapController instance.
    /// (Use sharedController method to avoid the need for setting the value again)
    /// - Parameter riskParameter: The risk parameter to set.
    public func set(riskParameter: EncapSwiftAPI.RiskParameter, withValue value: Bool)

    ///
    /// Initiating adding (activating) of a new, or update activated recovery method.
    ///
    /// - Parameter withToken: The token used to authorise the add or update request.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func startAddOrUpdateRecovery(withToken: EncapSwiftAPI.EncapToken, onCompletion: @escaping (Result<EncapSwiftAPI.StartAddOrUpdateRecoveryResult, EncapSwiftAPI.ErrorResult>) -> ())

    ///
    /// Complete adding or update of recovery method from the earlier created session.
    ///
    /// - Parameter withRecoveryMethod: The recovery method to activate or update.
    /// - Parameter tokenPurpose: Optional - when provided this operation will yield a EncapToken that can be used to authorise tokenised operations.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func finishAddOrUpdateRecovery(withRecoveryMethod: EncapSwiftAPI.RecoveryMethod, tokenPurpose: EncapSwiftAPI.TokenPurpose = .none, onCompletion: @escaping (Result<EncapSwiftAPI.FinishAddOrUpdateRecoveryResult, EncapSwiftAPI.ErrorResult>) -> ())

    ///
    /// Start a new recovery session by identifying ourselves and providing the recovery method that will be used to do the recovery.
    ///
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func startRecovery(onCompletion: @escaping (Result<EncapSwiftAPI.StartRecoveryResult, EncapSwiftAPI.ErrorResult>) -> ())

    ///
    /// Finish recovery with the auth method that the end-user want to be activated with.
    ///
    /// - Parameter withRecoveryMethod: The Recovery method to recover with.
    /// - Parameter authMethodToActivate: The Authentication method to activate. EncapAuthMethodDevice is always activated.
    /// - Parameter tokenPurpose: Optional - when provided this operation will yield a EncapToken that can be used to authorise tokenised operations.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    /// - Note If previously activated, this operation will deactivate the old registration data when started with valid parameters.
    public func finishRecovery(withRecoveryMethod: EncapSwiftAPI.RecoveryMethod, authMethodToActivate: EncapSwiftAPI.AuthMethod, tokenPurpose: EncapSwiftAPI.TokenPurpose = .none, onCompletion: @escaping (Result<EncapSwiftAPI.FinishRecoveryResult, EncapSwiftAPI.ErrorResult>) -> ())

    ///
    /// Start a recovery deletion session.
    /// - Parameter withToken: The token used to authorise the delete recovery request.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func startDeleteRecovery(withToken: EncapSwiftAPI.EncapToken, onCompletion: @escaping (Result<EncapSwiftAPI.StartDeleteRecoveryResult, EncapSwiftAPI.ErrorResult>) -> ())

    ///
    /// Finish deletion of a recovery method by providing the recovery method to delete.
    ///
    /// - Parameter withRecoveryMethod: The Recovery method to delete.
    /// - Parameter tokenPurpose: Optional - when provided this operation will yield a EncapToken that can be used to authorise tokenised operations.
    /// - Parameter onCompletion: The block that gives Result containing .success or .failure
    public func finishDeleteRecovery(withRecoveryMethod: EncapSwiftAPI.RecoveryMethod, tokenPurpose: EncapSwiftAPI.TokenPurpose = .none, onCompletion: @escaping (Result<EncapSwiftAPI.FinishDeleteRecoveryResult, EncapSwiftAPI.ErrorResult>) -> ())

    /// Checks if activation data is present on the device and returns activated authentication methods.
    /// It will not perform a check against Encap Server to check status of current activation.
    ///
    /// - Returns: Activated authentication methods, nil if not activated.
    public var activatedRecoveryMethods: Set<EncapSwiftAPI.RecoveryMethod> { get }

    /// Checks if recovery data is present on the device. It will not perform a check against Encap Server to check status of the activated recovery methods.
    ///
    /// - Returns: Result<Bool, ErrorResult>  containing a Bool or ErrorResult if an unexpected error occur during check.
    ///
    public func isRecoveryActivated() -> Result<Bool, EncapSwiftAPI.ErrorResult>
}

# EncapController Default Parameters

clientData is defaulted to nil in startAddOrupdate and startAuthentication, so that the method signature can be simplified when clientData is not being used.

# AuthMethod

EncapActivationParameters and EncapAuthParameter are removed in the SwiftAPI. They are replaced with the new enum type AuthMethod.

@frozen public enum AuthMethod {

    case unknown

    case device

    case pin(value: String)

    /// Using kSecAccessControlUserPresence
    /// Device passcode as fallback.
    /// - Parameter prompt: The message displayed to the end-user when prompted to authenticate using TouchID, for example context message sent from server.
    case touchID(prompt: String?)

    /// Using kSecAccessControlBiometryCurrentSet
    /// Data is invalidated when fingers are added or removed.
    /// - Parameter prompt: The message displayed to the end-user when prompted to authenticate using TouchID, for example context message sent from server.
    case strongTouchID(prompt: String?)

    /// Using kSecAccessControlBiometryCurrentSet.
    /// When Face ID is re-enrolled this item is invalidated.
    case faceID

    case offlineDevice

    case offlinePin(value: String)

    case offlineStrongTouchID(prompt: String?)

    case offlineFaceID
}

Useful information

The following have an associated value:

  • pin
  • touchID
  • strongTouchID
  • offlinePin
  • offlineStrongTouchID

In some cases, it can be useful to use the rawValue() for comparison when the value should not be taken in consideration.

Example of finishActivation with .faceID:

EncapController.shared.finishActivation(withAuthMethod: .faceID, onCompletion: ...

Example of finishAuthentication with .faceID:

EncapController.shared.finishAuthentication(withAuthMethod: .faceID, onCompletion: ...

# EncapInput and EncapTypes changed

EncapInputType is changed to InputType. For example:

@frozen public enum InputType {

    case any
    case numeric
    case alpha
    case alphaNumeric

    public func toUIKeyboardType() -> UIKeyboardType
    public func isValidFor(string: String) -> Bool
}
EncapAPI (Objective-C) EncapSwiftAPI (Swift)
UIKeyboardTypeFromEncapInputType(EncapInputType inputType) Moved to InputType and renamed to public function: toUIKeyboardType() -> UIKeyboardType
IsValidForEncapInputType(EncapInputType inputType, NSString *string) Moved to InputType and renamed to public function: isValidFor(string: String) -> Bool
Last updated: 11/04/2024 07:47 UTC