LogoLogo
Useful links
  • Home
  • Product guides
  • APIs
  • SDKs
  • Overview
  • Authentication
  • ANDROID
    • Getting Started with the SDK
    • Standalone Modules
      • Document Detector
        • Release Notes
        • Current Version
        • Requirements
        • Gradle Dependencies
        • Gradle Source Code
        • Setting up the SDK
          • Setting properties
          • Capture Stages
          • Messages Settings
          • Customization
          • Security Settings
          • Detection Steps
          • Upload Mode
          • Advanced Settings
            • Proxy configuration
            • Preview configuration
        • Start Document Detection
        • Source Code
        • Google security form
        • Reduce SDKs size
        • SDKs response
        • References
        • FAQ
      • Face Liveness
        • Release Notes
        • Current Version
        • Requirements
        • Gradle Dependencies
        • Gradle Source Code
        • SDK Lifecycle
        • Building the SDK
        • Start Liveness Verification
        • Source Code
        • References
        • Advanced Features
        • FAQ
      • Face Authenticator
        • Release Notes
      • Smart Auth
        • Release Notes
        • Current Version
        • Requirements
        • Gradle Dependencies
        • Gradle Source Code
        • Permissions
        • SDK Lifecycle
        • Building the SDK
        • Start Smart Authentication
        • Source Code
        • References
        • FAQ
      • Face Liveness (deprecated)
        • Release Notes
  • iOS
    • Getting Started with the SDK
    • Standalone Modules
      • Document Detector
        • Release Notes
        • Current Version
        • Requirements
        • Installing the SDK
        • Setting up the SDK
          • Setting properties
          • Messages Settings
          • Customization
          • Detection Steps
          • Upload Mode
          • Advanced Settings
            • Proxy configuration
            • Preview configuration
        • Start Document Detection
        • References
        • FAQ
      • Face Liveness
        • Release Notes
        • Installation
        • Current Version
        • Requirements
        • SDK Lifecycle
        • Building the SDK
        • Start Liveness Verification
        • Source Code
        • References
        • FAQ
      • Face Authenticator
        • Release Notes
        • Installation
        • Current Version
        • Requirements
        • Building the SDK
        • Start the SDK
        • References
        • FAQ
      • Smart Auth
        • Release Notes
        • Installation
        • Current Version
        • Requirements
        • SDK Lifecycle
        • Building the SDK
        • Start Smart Authentication
        • Source Code
        • References
        • FAQ
      • Face Liveness (deprecated)
        • Release Notes
  • REACT NATIVE
    • Standalone Modules
      • Document Detector
        • Release Notes
        • Current Version
        • Requirements
        • Installation
        • Hooks
        • Start Document Verification
        • Source Code
        • TypeScript References
        • Customizing Style
        • FAQ
      • Face Liveness
        • Release Notes
        • Current Version
        • Requirements
        • Installation
        • Hooks
        • Start Liveness Verification
        • Source Code
        • TypeScript References
        • FAQ
      • Face Authenticator
        • Release Notes
        • Current Version
        • Requirements
        • Installation
        • Hooks
        • Start Authentication Verification
        • Source Code
        • TypeScript References
        • FAQ
      • Smart Auth
        • Getting started
        • Release notes
        • Using Native Modules
          • Requirements
          • Gradle Source Code
          • Podfile Source Code
          • Native Module Android
          • Native Module iOS
          • Import Native Modules
          • Source Code
          • TypeScript References
          • FAQ
        • Using Expo Modules
          • Requirements
          • Create Local Expo Module
          • Gradle Source Code
          • Podspec Source Code
          • Native Module Android
          • Native Module iOS
          • Import Expo Modules
          • Source Code
          • TypeScript References
          • FAQ
  • WEB (JAVASCRIPT)
    • Standalone Modules
      • Document Detector
        • Getting started
        • SDK builder options
          • Analytics
          • Appearance
          • Messages
        • SDK methods
        • Event listeners
        • Customization
        • Release notes
      • Face Liveness
        • Customization
        • Release notes
      • Face Authenticator
        • Customization
        • Release notes
      • Smart Auth
        • SDK errors
        • Customization
        • Release notes
LogoLogo

Políticas

  • Política de depreciação de Recursos
  • Deprecation Policy for Resources

2025 © Caf. - All rights reserved

On this page
  • How to Create a Native Module in iOS
  • 1. Open the iOS Project in Xcode
  • 2. Create the Native Module
  • 3. Create the CafSmartAuthBridgeSettings.swift File
  • 4. Register the Native Module
  • 5. Create the Bridging Header for Swift and Objective-C
  1. REACT NATIVE
  2. Standalone Modules
  3. Smart Auth
  4. Using Native Modules

Native Module iOS

How to Create a Native Module in iOS

This detailed guide explains how to create a native module for the iOS platform within a React Native application. The process follows the step-by-step instructions from the official documentation.

1. Open the iOS Project in Xcode

First, open the iOS project of your React Native application in Xcode. You can find the iOS project in the folder: YourApp/ios/your-app-name.xcworkspace.

Using Xcode helps in quickly identifying issues, such as syntax errors, and provides powerful tools for iOS development.

2. Create the Native Module

Create a file named CafSmartAuthBridgeModule.swift in the directory ios/. This file will contain the class that implements the native module.

Key Functions of the CafSmartAuthBridgeModule Class

  • requiresMainQueueSetup: Indicates whether the module needs to be set up on the main queue. Returns true.

  • supportedEvents: Returns the list of events that the module can emit to React Native.

  • build: Creates and configures an instance of the CafSmartAuthSdk using the provided parameters.

  • emitEvent: Emits events from the native side to React Native.

  • setupListener: Sets up a listener to monitor the status of authentication operations.

  • startSmartAuth: A method exposed to React Native to initiate smart authentication.

Example Implementation of the CafSmartAuthBridgeModule.swift File

import Foundation
import React
import CafSmartAuth

private struct CafSmartAuthBridgeConstants { 
    static let cafSmartAuthSuccessEvent: String = "CafSmartAuth_Success"
    static let cafSmartAuthPendingEvent: String = "CafSmartAuth_Pending"
    static let cafSmartAuthErrorEvent: String = "CafSmartAuth_Error"
    static let cafSmartAuthCancelEvent: String = "CafSmartAuth_Cancel"
    static let cafSmartAuthLoadingEvent: String = "CafSmartAuth_Loading"
    static let cafSmartAuthLoadedEvent: String = "CafSmartAuth_Loaded"
    
    static let isAuthorized: String = "isAuthorized"
    static let attestation: String = "attestation"
    static let errorMessage: String = "message"

    static let cafFilterNaturalIndex: Int = 0

    static let backgroundColorHex: String = "#FFFFFF"
    static let textColorHex: String = "#FF000000"
    static let primaryColorHex: String = "#004AF7"
    static let boxBackgroundColorHex: String = "#0A004AF7"
}

@objc(CafSmartAuthBridgeModule)
class CafSmartAuthBridgeModule: RCTEventEmitter {
  private var smartAuth: CafSmartAuthSdk?
  
  @objc
  override static func requiresMainQueueSetup() -> Bool {
    return true
  }
  
  override func supportedEvents() -> [String]! {
    return [
      CafSmartAuthBridgeConstants.cafSmartAuthSuccessEvent,
      CafSmartAuthBridgeConstants.cafSmartAuthPendingEvent,
      CafSmartAuthBridgeConstants.cafSmartAuthErrorEvent,
      CafSmartAuthBridgeConstants.cafSmartAuthCancelEvent,
      CafSmartAuthBridgeConstants.cafSmartAuthLoadingEvent,
      CafSmartAuthBridgeConstants.cafSmartAuthLoadedEvent
    ]
  }
  
  private func build(
    mfaToken: String,
    faceAuthToken: String,
    settings: CafSmartAuthBridgeSettingsModel?
  ) -> CafSmartAuthSdk {
    let builder = CafSmartAuthSdk.CafBuilder(mobileToken: mfaToken)
    
    if let stage = settings?.stage, let cafStage = CAFStage(rawValue: stage) {
      _ = builder.setStage(cafStage)
    }

    if let emailUrl = settings?.emailUrl {
      _ = builder.setEmailURL(URL(string: emailUrl))
    }
    
    if let phoneUrl = settings?.phoneUrl {
      _ = builder.setPhoneURL(URL(string: phoneUrl))
    }
    
    let filter: CafFilterStyle = {
      if let faceSettings = settings?.faceAuthenticationSettings, faceSettings.filter == CafSmartAuthBridgeConstants.cafFilterNaturalIndex {
        return .natural
      }
      return .lineDrawing
    }()
    
    _ = builder.setLivenessSettings(
      CafFaceLivenessSettings(
        faceLivenessToken: faceAuthToken,
        useLoadingScreen: settings?.faceAuthenticationSettings?.loadingScreen ?? false,
        filter: filter
      )
    )

    let lightTheme = settings?.theme?.lightTheme
    let darkTheme = settings?.theme?.darkTheme
    
    _ = builder.setThemeConfigurator(
      CafThemeConfigurator(
        lightTheme: parseTheme(theme: lightTheme),
        darkTheme: parseTheme(theme: darkTheme)
      )
    )
    
    return builder.build()
  }

  private func parseTheme(theme: CafSmartAuthBridgeTheme?) -> CafTheme {
    if theme != nil {
      return CafTheme(
        backgroundColor: theme?.backgroundColor ?? CafSmartAuthBridgeConstants.backgroundColorHex,
        textColor: theme?.textColor ?? CafSmartAuthBridgeConstants.textColorHex,
        linkColor: theme?.linkColor ?? CafSmartAuthBridgeConstants.primaryColorHex,
        boxBorderColor: theme?.boxBorderColor ?? CafSmartAuthBridgeConstants.primaryColorHex,
        boxFilledBorderColor: theme?.boxFilledBorderColor ?? CafSmartAuthBridgeConstants.primaryColorHex,
        boxBackgroundColor: theme?.boxBackgroundColor ?? CafSmartAuthBridgeConstants.boxBackgroundColorHex,
        boxFilledBackgroundColor: theme?.boxFilledBackgroundColor ?? CafSmartAuthBridgeConstants.boxBackgroundColorHex,
        boxTextColor: theme?.boxTextColor ?? CafSmartAuthBridgeConstants.primaryColorHex,
        progressColor:  theme?.progressColor ?? CafSmartAuthBridgeConstants.primaryColorHex
      )
    } else {
      return CafTheme(
        backgroundColor: CafSmartAuthBridgeConstants.backgroundColorHex,
        textColor: CafSmartAuthBridgeConstants.textColorHex,
        linkColor: CafSmartAuthBridgeConstants.primaryColorHex,
        boxBorderColor: CafSmartAuthBridgeConstants.primaryColorHex,
        boxFilledBorderColor: CafSmartAuthBridgeConstants.primaryColorHex,
        boxBackgroundColor: CafSmartAuthBridgeConstants.boxBackgroundColorHex,
        boxFilledBackgroundColor: CafSmartAuthBridgeConstants.boxBackgroundColorHex,
        boxTextColor: CafSmartAuthBridgeConstants.primaryColorHex,
        progressColor: CafSmartAuthBridgeConstants.primaryColorHex
      )
    }
  }
  
  private func emitEvent(name: String, data: Any) {
    self.sendEvent(withName: name, body: data)
  }
  
  private func setupListener() -> CafVerifyPolicyListener {
    return { result in
      switch result {
      case .onSuccess(let response):
        self.emitEvent(
          name: CafSmartAuthBridgeConstants.cafSmartAuthSuccessEvent,
          data: [
            CafSmartAuthBridgeConstants.isAuthorized: response.isAuthorized,
            CafSmartAuthBridgeConstants.attestation: response.attestation
          ]
        )
        self.smartAuth = nil
        
      case .onPending(let response):
        self.emitEvent(
          name: CafSmartAuthBridgeConstants.cafSmartAuthPendingEvent,
          data: [
            CafSmartAuthBridgeConstants.isAuthorized: response.isAuthorized,
            CafSmartAuthBridgeConstants.attestation: response.attestation
          ]
        )
        
      case .onError(let error):
        self.emitEvent(
          name: CafSmartAuthBridgeConstants.cafSmartAuthErrorEvent,
          data: [CafSmartAuthBridgeConstants.errorMessage: error.error.localizedDescription]
        )
        self.smartAuth = nil
        
      case .onCanceled(_):
        self.emitEvent(
          name: CafSmartAuthBridgeConstants.cafSmartAuthCancelEvent,
          data: true
        )
        self.smartAuth = nil
        
      case .onLoading:
        self.emitEvent(name: CafSmartAuthBridgeConstants.cafSmartAuthLoadingEvent, data: true)
        
      case .onLoaded:
        self.emitEvent(name: CafSmartAuthBridgeConstants.cafSmartAuthLoadedEvent, data: true)
      }
    }
  }
  
  
  @objc(startSmartAuth:livenessToken:personId:policyId:settings:)
  func startSmartAuth(mfaToken: String, faceAuthToken: String, personId: String, policyId: String, settings: String?) {
    DispatchQueue.main.async {
      self.smartAuth = self.build(
        mfaToken: mfaToken, faceAuthToken: faceAuthToken, settings: CafSmartAuthBridgeSettings().parseJson(settings: settings)
      )
      
      self.smartAuth?.verifyPolicy(personID: personId, policyId: policyId, listener: self.setupListener())
    }
  }
}

3. Create the CafSmartAuthBridgeSettings.swift File

This file will handle the interpretation of data sent from React Native to the native module.

Example Implementation:

import Foundation
import CafSmartAuth

internal struct CafFaceAuthenticationSettingsModel: Decodable {
  let loadingScreen: Bool?
  let filter: Int?
}

internal struct CafSmartAuthBridgeTheme: Decodable {
  let backgroundColor: String?
  let textColor: String?
  let progressColor: String?
  let linkColor: String?
  let boxBackgroundColor: String?
  let boxFilledBackgroundColor: String?
  let boxBorderColor: String?
  let boxFilledBorderColor: String?
  let boxTextColor: String?
}

internal struct CafSmartAuthBridgeThemeConfigurator: Decodable {
  let lightTheme: CafSmartAuthBridgeTheme?
  let darkTheme: CafSmartAuthBridgeTheme?
}


internal struct CafSmartAuthBridgeSettingsModel: Decodable {
  let stage: Int?
  let faceAuthenticationSettings: CafFaceAuthenticationSettingsModel?
  let emailUrl: String?
  let phoneUrl: String?
  let theme: CafSmartAuthBridgeThemeConfigurator?
}

internal class CafSmartAuthBridgeSettings {
  internal func parseJson(settings: String?) -> CafSmartAuthBridgeSettingsModel? {
    guard let data = settings?.data(using: .utf8) else {
      return nil
    }
    
    do {
      let decoder = JSONDecoder()
      let parsedSettings = try decoder.decode(CafSmartAuthBridgeSettingsModel.self, from: data)
      
      return parsedSettings
    } catch {
      return nil
    }
  }
}

4. Register the Native Module

Create the main header and implementation files for the custom native module. Create a new file named CafSmartAuthBridge.h.

Example Implementation:

#import <React/RCTBridgeModule.h>

@interface CafSmartAuthBridgeModule : NSObject <RCTBridgeModule>

@end

To make the native module recognizable by React Native, create the file CafSmartAuthBridge.mm in the same directory:

Example Implementation:

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface RCT_EXTERN_MODULE(CafSmartAuthBridgeModule, RCTEventEmitter)
RCT_EXTERN_METHOD(startSmartAuth:(NSString *)mfaToken livenessToken:(NSString *)livenessToken personId:(NSString *)personId policyId:(NSString *)policyId settings:(NSString *)settings)
@end

5. Create the Bridging Header for Swift and Objective-C

Whenever you mix Swift and Objective-C in an iOS project, a bridging header file is required. This file allows Swift to access functionalities implemented in Objective-C, including React Native APIs.

In the same directory as the Swift file, create the file CafSmartAuthBridge-Bridging-Header.h.

Example Implementation of the Bridging Header File

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

Configuration Steps

  1. Ensure the CafSmartAuthBridge-Bridging-Header.h file is included in the Objective-C Bridging Header field in Build Settings (Build Settings > Swift Compiler - General > Objective-C Bridging Header).

  2. Provide the relative path to the file, e.g.,

    YourApp/ios/YourApp/CafSmartAuthBridge-Bridging-Header.h

Last updated 1 month ago