The MIRACL Trust iOS SDK provides the following functionalities:
- User ID Verification
- Registration
- Authentication
- Signing
- Cross-Device Session
- QuickCode
- User Management
- Xcode 13 or newer
- iOS 15 or newer
- Swift 4.2 or newer
If you use Xcode go to Project Settings -> Package Dependencies -> Click the
add button (+) and add the package repo:
https://github.com/miracl/trust-sdk-iosTo integrate using Apple's Swift package manager, without Xcode integration, add the following as a dependency to your Package.swift:
.package(url: "https://github.com/miracl/trust-sdk-ios", .upToNextMajor(from: "1.20.0"))In both cases after the package is downloaded, go to the Target's General tab,
Expand the Frameworks, Libraries, and Embedded Content section, click the Add
button (+) and select MIRACLTrust framework.
The MIRACL Trust iOS SDK provides its own podspec repository. If you want to
integrate MIRACL Trust iOS SDK into your application, add the MIRACL Trust iOS
SDK podspec source to your Podfile:
source 'https://github.com/miracl/cocoapods-specs'
source 'https://github.com/CocoaPods/Specs'Next step is to add the MIRACLTrust iOS SDK pod to your target:
pod 'MIRACLTrust', '~> 1.20.0'For more information on how to add Cocoapods sources check the documentation.
Drag and drop the XCFramework to your application.
To configure the SDK:
- Create an account in the MIRACL Trust platform. For information about how to do it, see the Getting Started guide.
- Call the configure method with a configuration created by the Configuration.Builder class using your project properties:
Swift:
let projectId = <#Enter your Project ID here#>
let projectURL = <#Enter your Project Domain here#>
let deviceName = <#Enter your device name here or use UIDevice.current.modelName provided by MIRACL Trust iOS SDK #>
do {
let configuration = try Configuration
.Builder(
projectId: projectId,
projectURL: projectURL,
deviceName: deviceName
).build()
try MIRACLTrust.configure(with: configuration)
} catch {
<#Handle error as appropriate#>
}Objective-C:
NSString *projectId = <#Enter your Project ID#>;
NSString *projectURL = <#Enter your Project Domain here#>;
NSString *deviceName = <#Enter your device name here or use UIDevice.current.modelName provided by MIRACL Trust SDK #>;
NSError *configurationError;
ConfigurationBuilder *configurationBuilder =
[[ConfigurationBuilder alloc] initWithProjectId: projectId
projectURL: projectURL
deviceName: deviceName];
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.
deviceName is an identifier that can help find the device on the MIRACL Trust
Portal. For iOS, the MIRACL Trust SDK provides a UIDevice.modelName
extension that returns the actual model name of the device (e.g iPhone 16 Pro
Max). This extension value can be passed to the
Configuration.Builder
constructor. By default, the value of deviceName is the name of the operation
system (e.g iOS).
To obtain an instance of the SDK, call the getInsatnce method:
Swift:
let miraclTrust = MIRACLTrust.getInstance()Objective-C:
MIRACLTrust *miraclTrust = [MIRACLTrust getInstance];To register a new User ID, you need to verify it. MIRACL offers two options for that:
-
With this type of verification, the end user's email address serves as the User ID. Currently, MIRACL Trust provides two kinds of built-in email verification methods:
- Email Link (default)
- Email Code
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 verification email is sent and handle any verification errors. }
Objective-C:
[[MIRACLTrust getInstance] sendVerificationEmailWithUserId: <#Unique user identifier#> authenticationSessionDetails: nil completionHandler: ^(VerificationResponse *verificationResponse, NSError * _Nullable error) { // Check here if verification email // is sent and handle any verification errors. }];
Then, a verification email is sent, and a VerificationResponse with backoff and email verification method is returned.
If the verification method you have chosen for your project is:
-
Email Code:
You must check the email verification method in the response.
-
If the end user is registering for the first time or resetting their PIN, an email with a verification code will be sent, and the email verification method in the response will be EmailVerificationMethod.code. Then, ask the user to enter the code in the application.
-
If the end user has already registered another device with the same User ID, a Verification URL will be sent, and the verification method in the response will be EmailVerificationMethod.link. In this case, proceed as described for the Email Link verification method below.
-
-
Email Link: Your application must open when the end user follows the Verification URL in the email. To ensure proper deep linking behaviour on mobile applications, use Apple's Universal Links. To associate your application with the email Verification URL, use the iOS app association field in Mobile Applications under Configuration in the MIRACL Trust Portal.
-
To register the mobile device, get an activation token. This happens in two different ways depending on type of verification.
-
Custom User Verification or Email Link:
After the application recieves the Verification URL, it must confirm the verification by passing it to the getActivationToken method:
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
UIKitapplications, use the scene or application delegate methods. ForSwiftUI, use the onOpenURL modifier. -
When the end user enters the verification code, the application must confirm the verification by passing it to the getActivationToken method:
Swift:
MIRACLTrust .getInstance() .getActivationToken(userId: userId, code: code) { activationTokenResponse, error in // Pass the activation token to the `register` method. }
Objective-C:
[[MIRACLTrust getInstance] getActivationTokenWithUserId:userId code:code completionHandler:^(ActivationTokenResponse * _Nullable response, NSError * _Nullable error) { // Pass the activation token to the `register` method. }];
-
-
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.
То authenticate users on your mobile application, call the authenticate method. If the authentication is successful, a JWT authentication token is generated for a registered user.
Swift:
MIRACLTrust.getInstance().authenticate(
user: <#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.
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#> ,
user: <#Already registered user#>,
didRequestSigningPinHandler: { pinProcessor in
// Here the user provides their current signing PIN.
pinProcessor(<#Provide your signing user PIN here#>)
}, completionHandler: { signingResult, error in
// The signingResult object contains signature and timestamp,
// and can be sent for verification.
}
)Objective-C:
[[MIRACLTrust getInstance] signWithMessage: <#Message hash#>
user: <#Already registered signing user#>
didRequestSigningPinHandler: ^(void (^ _Nonnull pinProcessor)(NSString * _Nullable)) {
// Here the user provides their current signing PIN.
pinProcessor(<#Provide your signing user PIN here#>);
} completionHandler: ^(SigningResult * _Nullable signingResult, NSError * _Nullable error) {
// The signingResult object contains signature and timestamp,
// and can be sent 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 and the
timestamp are 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.
The MIRACL Trust iOS SDK provides an API for handling cross-device sessions
initiated from external applications, allowing users to authenticate or sign
documents on a mobile device.A cross-device session is created by calling the
createCrossDeviceSession method of the
MIRACL Trust Client JS Library. Then it
can be fetched via
universal links,
QR codes, or
push notifications.
Once the cross-device session is successfully fetched, you can proceed to
authenticate the end user or sign a document using the corresponding SDK
methods. If the session is no longer needed, you can abort it to cancel the
current cross-device operation.
Depending on how the cross-device session is initiated, there are three options to fetch it:
-
Via universal link
Use the getCrossDeviceSessionFromUniversalLinkURL method:
Swift:
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { guard let universalLinkURL = userActivity.webpageURL else { return } MIRACLTrust .getInstance() .getCrossDeviceSessionFromUniversalLinkURL( universalLinkURL: universalLinkURL ) { crossDeviceSession, error in // Use the cross device session or handle the error appropriately. } }
Objective-C:
-(void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity { if(userActivity.webpageURL == nil) { return; } NSURL *universalLinkURL = userActivity.webpageURL; [[MIRACLTrust getInstance] getCrossDeviceSessionFromUniversalLinkURL:universalLinkURL completionHandler:^( CrossDeviceSession *crossDeviceSession, NSError *error ) { // Use the cross device session or handle the error appropriately. }]; }
Call this method after the Universal Link is handled in the application. For
UIKitapplications, use the scene or application delegate methods. ForSwiftUI, use the onOpenURL modifier. -
Via QR code:
Use the getCrossDeviceSessionFromQRCode method:
Swift:
MIRACLTrust .getInstance() .getCrossDeviceSessionFromQRCode( qrCode: <#QR code taken from a MIRACL Trust page#> ) { crossDeviceSession, error in // Use the cross device session or handle the error appropriately. }
Objective-C:
[[MIRACLTrust getInstance] getCrossDeviceSessionFromQRCode:<#QR code taken from a MIRACL Trust page#> completionHandler:^( CrossDeviceSession * crossDeviceSession, NSError * error ) { // Use the cross device session or handle the error appropriately. }];
-
Via push notification:
Use the getCrossDeviceSessionFromPushNotificationPayload method:
Swift:
func userNotificationCenter( _ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void ) { let pushPayload = response.notification.request.content.userInfo MIRACLTrust .getInstance() .getCrossDeviceSessionFromPushNotificationPayload( pushNotificationPayload: pushPayload ) { crossDeviceSession, error in // Use the cross device session or handle the error appropriately. } }
Objective-C:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { NSDictionary *pushPayload = notification.request.content.userInfo; [[MIRACLTrust getInstance] getCrossDeviceSessionFromPushNotificationPayload:pushPayload completionHandler:^( CrossDeviceSession * crossDeviceSession, NSError *error ) { // Use the cross device session or handle the error appropriately. }]; }
After fetching the cross-device session, you can proceed with either authentication or document signing. To determine which operation the session is intended for, check its type property.
Authenticate using the authenticateCrossDeviceSession method:
Swift:
MIRACLTrust.getInstance().authenticateCrossDeviceSession(
crossDeviceSession
user: user
) { pinProcessor in
// Here the user provides their current User ID's PIN code.
pinProcessor(<#Provide your PIN here#>)
} completionHandler: { isAuthenticated, error in
// Handle your authentication result here.
}Objective-C:
[[MIRACLTrust getInstance]
authenticateCrossDeviceSession:crossDeviceSession
user:user
didRequestPinHandler:^(void (^ pinProcessor)(NSString *)) {
// Here the user provides their current User ID's PIN code.
pinProcessor(<#Provide your PIN here#>);
} completionHandler:^(BOOL isAuthenticated, NSError * error) {
// Handle your authentication result here.
}];Sign a document with the signCrossDeviceSession method:
Swift:
MIRACLTrust
.getInstance()
.signCrossDeviceSession(
crossDeviceSession,
user: user
) { processPinHandler in
// Here the user provides their current User ID's PIN code.
pinProcessor(<#Provide your PIN here#>)
} completionHandler: { isSigned, error in
// Handle your signing result here.
}Objective-C:
[[MIRACLTrust getInstance]
signCrossDeviceSession:crossDeviceSession
user:user
didRequestSigningPinHandler:
^(void (^ _Nonnull pinProcessor)(NSString * _Nullable)
) {
// Here the user provides their current User ID's PIN code.
pinProcessor(<#Provide your PIN here#>)
} completionHandler:^(BOOL isSigned, NSError * _Nullable error) {
// Handle your signing result here.
}];To cancel the handling of the cross-device session, call the abortCrossDeviceSession method:
Swift:
MIRACLTrust
.getInstance()
.abortCrossDeviceSession(
crossDeviceSession
) { isAborted, error in
// Handle session aborting result here.
}Objective-C:
[[MIRACLTrust getInstance]
abortCrossDeviceSession:crossDeviceSession
completionHandler:^(BOOL isAborted, NSError * error) {
// Handle session aborting result here.
}];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.
}];The MIRACL Trust iOS SDK provides several methods for managing users registered on a device. These operations allow you to retrieve user information or delete previously registered users.
To retrieve a specific registered user by their User ID, use the getUser(userId:completionHandler) method:
Swift:
MIRACLTrust.getInstance().getUser(userId: userId) { user, error in
if let user {
// User exists.
} if let error {
// Cannot retrieve the user due to an error.
} else {
// No user registered with this User ID.
}
}Objective-C:
[[MIRACLTrust getInstance]
getUserWithUserId: userId
completionHandler:^(User * user, NSError *error) {
if (user != nil) {
// User exists.
} else if (error != nil) {
// Cannot retrieve the user due to an error.
} else {
// No user registered with this User ID.
}
}];To obtain the list of all users registered on а device, access the getUsers(completionHandler:) method:
Swift:
MIRACLTrust.getInstance().getUsers { users, error in
// Handle registered users.
}Objective-C:
[[MIRACLTrust getInstance] getUsersWithCompletionHandler:^(NSArray<User *> * users, NSError * error) {
// Handle registered users.
}];To delete a previously registered user from a device, call the delete(user:completionHandler:) method:
Swift:
MIRACLTrust.getInstance().delete(user: user) { isDeleted, error in
if isDeleted {
// User deleted successfully.
} else if let error {
// Cannot delete the user due to an error.
}
}Objective-C:
[[MIRACLTrust getInstance]
deleteWithUser: user
completionHandler:^(BOOL isDeleted, NSError * error) {
if (isDeleted) {
// User deleted successfully.
} else if (error != nil) {
// Cannot delete the user due to an error.
}
}];-
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) }
-
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:
-
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:
- Go to trust.miracl.cloud.
- Log in or create a new User ID.
- Select your project.
- In the CONFIGURATION section, go to General.
- Copy the Project ID value.