MIRACL Trust iOS SDK

The MIRACL Trust iOS SDK provides the following functionalities:

# System Requirements

  • Xcode 10 or newer
  • iOS 11 or newer
  • Swift 4.2 or newer

# Installation

# Manual

Contact us at support@miracl.com to get the latest framework version and drag and drop it to your application.

# Usage

# SDK Configuration

To configure the SDK:

  1. Create an application in the MIRACL Trust platform. For information about how to do it, see the Getting Started guide.
  2. Call the configure method with a configuration created by the Configuration.Builder class:

Swift:

let projectId = <#Enter your Project ID here#>

do {
    let configuration = try Configuration
        .Builder(
            projectId: projectId
        ).build()
    try MIRACLTrust.configure(with: configuration)
} catch {
    <#Handle error as appropriate#>
}

Objective-C:

NSString *projectId = <#Enter your Project ID#>;
NSError *configurationError;

ConfigurationBuilder *configurationBuilder =
    [[ConfigurationBuilder alloc] initWithProjectId:projectId];
Configuration *configuration =
    [configurationBuilder buildAndReturnError:&configurationError];

if (configurationError == nil) {
    [[MIRACLTrust configureWith:configuration
                          error:&configurationError];

    if (configurationError != nil) {
        <#Handle error as appropriate#>
    }
}

Call the configure method as early as possible in the application lifecycle and avoid using the getInstance method before that; otherwise assertion will be triggered.

# Obtain instance of the SDK

To obtain an instance of the SDK, call the getInsatnce method:

Swift:

let miraclTrust = MIRACLTrust.getInstance()

Objective-C:

MIRACLTrust *miraclTrust = [MIRACLTrust getInstance];

# User ID Verification

To register a new User ID, you need to verify it. MIRACL offers two options for that:

  • Custom User Verification.

  • Default verification - Confirm the User ID via email message.

    The default verification uses Apple’s Universal Links to navigate back to the application from the email message. That is why the Associated Domains capability is required.

    Start the verification by calling the sendVerificationEmail method:

    Swift:

        MIRACLTrust.getInstance().sendVerificationEmail(
            userId: <#Unique user identifier (any string, i.e. email)#>
        ) { (verificationResponse, error) in
           // Check here if User ID is verified and handle any verification errors.
        }
    

    Objective-C:

        [[MIRACLTrust getInstance]
            sendVerificationEmailWithUserId: <#Unique user identifier#>
               authenticationSessionDetails: nil
                          completionHandler: ^(VerificationResponse *verificationResponse, NSError * _Nullable error) {
                              // Check here if User ID
                              // is verified and handle any verification errors.
                          }];
    

# Registration

  1. To register the mobile device, get an activation token using the getActivationToken method and the received verification URL:

    Swift:

    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        guard let verificationURL = userActivity.webpageURL else {
            return
        }
    
        MIRACLTrust
            .getInstance()
            .getActivationToken(verificationURL: verificationURL) { activationTokenResponse, error in
                    // Pass the activation token to the `register` method.
            }
    }
    

    Objective-C:

    -(void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity
    {
        if(userActivity.webpageURL == nil) {
            return;
        }
    
        NSURL *verificationURL = userActivity.webpageURL;
    
        [[MIRACLTrust getInstance]
            getActivationTokenWithVerificationURL:verificationURL
            completionHandler: ^(ActivationTokenResponse * _Nullable activationTokenResponse,
                                NSError * _Nullable error) {
                                // Pass the activation token to the `register` method.
            }];
    }
    

    Call this method after the Universal Link is handled in the application. For UIKit applications, use the scene or application delegate methods. For SwiftUI, use the onOpenURL modifier.

  2. Pass the User ID (email or any string you use for identification), activation token (received from verification), PinRequestHandler and RegistrationCompletionHandler implementations to the register method. When the registration is successful, a RegistrationCompletionHandler callback is returned, passing the registered user. Otherwise RegistrationError is passed in the callback.

    Swift:

    MIRACLTrust.getInstance().register(
        for: <#Unique user identifier (any string, i.e. email)#>,
        activationToken: <#Activation token#>,
        didRequestPinHandler: { pinProcessor in
            // Here the user creates a PIN code for their new User ID.
    
            pinProcessor(<#Provide your PIN code here#>)
        },
        completionHandler: { user, error in
        // Get the user object or handle the error appropriately.
        }
    )
    

    Objective-C:

    [[MIRACLTrust getInstance] registerFor:<#Unique user identifier (any string, i.e. email)#>
                        activationToken:<#Activation token#>
                    pushNotificationsToken:<#Push notifications token#>
                    didRequestPinHandler:^(void (^ _Nonnull pinProcessor)(NSString *)) {
                        // Here the user creates a PIN code for their new User ID.
    
                        pinProcessor(<#Provide your PIN code here#>)
                    } completionHandler:^(User * _Nullable user, NSError * _Nullable error) {
                        // Get the user object or handle the error appropriately.
                    }];
    

    If you call the register method with the same User ID more than once, the User ID will be overridden. Therefore, you can use it when you want to reset your authentication PIN code.

# Authentication

The MIRACL Trust SDK offers two options:

# Authenticate users on the mobile application

The authenticate method generates a JWT authentication token for а registered user.

Swift:

    MIRACLTrust.getInstance().authenticate(
        for: <#Already registered user object#>
    ) { pinHandler in
        // Here the user provides their current User ID's PIN code.

        pinHandler(<#Provide your PIN here#>)
    } completionHandler: { jwt, error in
        // Get the JWT or handle the error appropriately.
    }

Objective-C:

[[MIRACLTrust getInstance] authenticate:<#Already registered user object#>
                   didRequestPinHandler:^(void (^ _Nonnull pinHandler)(NSString * _Nullable)) {
                         pinHandler(<#Provide your PIN here#>);
                    } completionHandler:^(NSString * _Nullable jwt, NSError * _Nullable error) {
                          // Get the JWT or handle the error appropriately.
                    }];

After the JWT authentication token is generated, it needs to be sent to the application server for verification. Then, the application server verifies the token signature using the MIRACL Trust JWKS endpoint and the audience claim, which in this case is the application Project ID.

# Authenticate users on another application

To authenticate a user on another application, there are three options:

  • Authenticate with Universal Links

    Use the authenticateWithUniversalLinkURL method:

    Swift:

    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        guard let universalLinkURL = userActivity.webpageURL else {
            return
        }
    
        MIRACLTrust.getInstance().authenticateWithUniversalLinkURL(
            user: <#Already registered user object#>,
            universalLinkURL: universalLinkURL,
            didRequestPinHandler: { pinHandler in
                // Here the user provides their current User ID's PIN code.
    
                pinHandler(<#Provide your PIN here#>)
            } completionHandler { isAuthenticatedResult, error in
                // Handle your authentication result here.
            }
    }
    

    Objective-C:

    -(void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
        if(userActivity.webpageURL == nil) {
            return;
        }
    
        NSURL *universalLinkURL = userActivity.webpageURL;
    
        [[MIRACLTrust getInstance] authenticateWithUser:<#Already registered user object#>
            universalLinkURL:universalLinkURL
        didRequestPinHandler:^(void (^ _Nonnull pinProcessor)(NSString * _Nullable)) {
            pinHandler(<#Provide your PIN here#>);
        } completionHandler:^(BOOL isAuthenticated, NSError * _Nullable error) {
            // Handle your authentication result here.
        }];
    }
    

If your application doesn’t use UIScene, add the authenticateWithUniversalLinkURL implementation to the application:continueUserActivity:restorationHandler: implementation in the Application Delegate.

If using SwiftUI, use the onOpenURL modifier.

  • Authenticate with QR code

    Use the authenticateWithQRCode method:

    Swift:

        MIRACLTrust.getInstance().authenticateWithQRCode(
            user: <#Already registered user object#>,
            qrCode: <#QR code taken from a MIRACL page#>,
            didRequestPinHandler: { pinProcessor in
                // Here the user provides their current User ID's PIN code.
    
                pinProcessor(<#Provide your PIN code here#>)
            }, completionHandler: { isAuthenticatedResult, error in
                // Handle your authentication result here.
            }
        )
    

    Objective-C:

    [[MIRACLTrust getInstance]
        authenticateWithUser:<#Already registered user object#>
                      qrCode:<#QR code taken from a MIRACL page#>
        didRequestPinHandler:^(void (^ _Nonnull pinProcessor)(NSString * _Nullable)) {
            // Here the user provides their current User ID's PIN code.
    
            pinProcessor(<#Provide your PIN here#>);
        } completionHandler:^(BOOL isAuthenticated, NSError * _Nullable error) {
            // Handle your authentication result here.
        }];
    
  • Authenticate with push notifications payload:

    Use the authenticateWithPushNotificationPayload method:

    Swift:

    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        let pushPayload = response.notification.request.content.userInfo
    
        MIRACLTrust
            .getInstance()
            .authenticateWithPushNotificationPayload(
                payload: pushPayload,
                didRequestPinHandler: { pinProcessor in
                    // Here the user provides their current User ID's PIN code.
    
                    pinProcessor(<#Provide your PIN code here#>)
                },
                completionHandler: { isAuthenticatedResult, error in
                    // Handle your authentication result here.
                }
            )
    }
    

    Objective-C:

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center
           willPresentNotification:(UNNotification *)notification
             withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
    {
        NSDictionary *pushPayload = notification.request.content.userInfo;
    
        [[MIRACLTrust getInstance]
            authenticateWithPushNotificationPayload:pushPayload
            didRequestPinHandler:^(void (^ _Nonnull pinHandler)(NSString * _Nullable)) {
                // Here the user provides their current User ID's PIN code.
    
                pinProcessor(<#Provide your PIN here#>);
            } completionHandler:^(BOOL isAuthenticated, NSError * _Nullable error) {
                // Handle your authentication result here.
            }];
    }
    

For more information about authenticating users on custom applications, see Cross-Device Authentication.

# Signing

DVS stands for Designated Verifier Signature, which is a protocol for cryptographic signing of documents. For more information, see Designated Verifier Signature. In the context of this SDK, we refer to it as ‘Signing’.

To sign a document, use the sign method as follows:

Swift:

MIRACLTrust.getInstance().sign(
    message: <#Message hash#> ,
    timestamp: <#The time when the signature was created#>,
    user: <#Already registered user#>,
    didRequestSigningPinHandler: { pinProcessor in
        // Here the user provides their current signing PIN.

        pinProcessor(<#Provide your signing user PIN here#>)
    }, completionHandler: { signature, error in
        // The signature object can be sent to the server for verification.
    }
)

Objective-C:

[[MIRACLTrust getInstance] signWithMessage: <#Message hash#>
                                 timestamp: <#The time when the signature was created#>
                                      user: <#Already registered signing user#>
                     signingSessionDetails: <#Signing session details, if used, othewise nil#>
               didRequestSigningPinHandler: ^(void (^ _Nonnull pinProcessor)(NSString * _Nullable)) {
                    // Here the user provides their current signing PIN.

                    pinProcessor(<#Provide your signing user PIN here#>);
                } completionHandler: ^(Signature * _Nullable signature, NSError * _Nullable error) {
                    // The signature object can be sent to the server for verification.
                }];

The signature is generated from a document hash. To get this hash, you can use the CryptoKit or CommonCrypto frameworks.

The signature needs to be verified. This is done when the signature is sent to the application server, which then makes a call to the POST /dvs/verify endpoint. If the MIRACL Trust platform returns status code 200, the certificate entry in the response body indicates that signing is successful.

# QuickCode

QuickCode is a way to register another device without going through the verification process.

To generate a QuickCode, call the generateQuickCode method with an already registered User object:

Swift:

MIRACLTrust.getInstance().generateQuickCode(
    for: <#Already registered user#>,
    didRequestPinHandler: { pinHandler in
        // Here the user provides their current User ID's PIN code.
        pinHandler(<#Provide your user PIN here#>)
    },
    completionHandler: { quickCode, error in
        // Get the QuickCode object or handle the error appropriately.
    }
)

Objective-C:

 [[MIRACLTrust getInstance]
        generateQuickCode:<#Already registered  user#>
     didRequestPinHandler:^(void (^ _Nonnull pinHandler)(NSString * _Nullable)) {
        // Here the user provides their current authentication PIN.

        pinHandler(<#Provide your user PIN here#>);
     } completionHandler:^(QuickCode * _Nullable quickCode , NSError * _Nullable error) {
        // Get the QuickCode object or handle the error appropriately.
     }];

# FAQ

  1. How to provide a PIN code?

    For security reasons, the PIN code is sent to the SDK at the last possible moment. A PinRequestHandler is responsible for that and when the SDK calls it, the currently executed operation is blocked until a PIN code is provided. Therefore, this is a good place to display some user interface for entering the PIN code. For example:

    Swift:

    MIRACLTrust.getInstance().register(
        for: <#Unique user identifier(i.e. email)#>,
        activationToken: <#Activation token#>,
        didRequestPinHandler: { pinProcessor in
            let enterPinViewController = EnterPinViewController()
            enterPinViewController.pinProcessor = pinProcessor
    
            present(enterPinViewController, animated:true)
        },
        completionHandler: { user, error in
           // Get the user object or handle the error appropriately.
        }
    )
    

    In the view controller for entering the PIN code, you need to call the pinProcessor closure, which sends the PIN code to the SDK and restores the previously executed operation:

    Swift:

    func submitPINCode() {
        let pinCodeText = <#Get your PIN code here.>
    
        pinProcessor(pinCodeText)
    }
    
  2. What is Activation Token?

    Activation Token is the value that links the verification flow with the registration flow. The value is returned by the verification flow and needs to be passed to the register method so the platform can verify it. Here are the options for that:

  3. What is Project ID?

    Project ID is a common identifier of applications in the MIRACL Trust platform that share a single owner.

    You can find the Project ID value in the MIRACL Trust Portal:

    1. Go to trust.miracl.cloud.
    2. Log in or create a new User ID.
    3. Select your project.
    4. In the CONFIGURATION section, go to General.
    5. Copy the Project ID value.

# Documentation