This guide explains how to build a React Native native module - PrismCapture - that wraps the body-scan capture experience only of PrismSDK for both iOS and Android behind one unified JS/TS API. The module presents the full-screen capture UX, receives the output zip, and performs a direct PUT upload to an S3 presigned URL that your backend obtains from the Prism API. No Prism API credentials are needed on the device; all REST calls (user management, scan records, measurements, health reports) remain on the backend and are out of scope for this module.
Wraps:
.zip file written to local storage.Content-Type: application/zip).Does NOT wrap:
PrismSDK-Info.plist on iOS and no API credentials on Android.JS Layer
└── NativeModules.PrismCapture ← one JS surface
├── iOS: PrismCapture.swift / PrismCapture.m (RCTEventEmitter)
│ presents PrismSessionViewController (UIKit) or UIHostingController<PrismSessionView>
│ FileUploader (PrismLink) for background S3 PUT
└── Android: PrismCaptureModule.kt (ReactContextBaseJavaModule)
launches PrismCaptureActivity (ComponentActivity + Compose)
PrismSessionView Composable wraps PrismSession controller
Ktor client for S3 PUT
New Architecture note: On RN New Architecture (Fabric / JSI), this module becomes a TurboModule. The JS surface - method names, event names, payload shapes - is identical. The bridge registration code (
.mfile on iOS,Packageon Android) is the only mechanical change; swapRCT_EXTERN_MODULEfor the codegen spec and register viaReactPackageTurboModuleManagerDelegateon iOS, and implement the generatedNativePrismCaptureTurboModulespec on Android.
| RN Method | What it does | Platform notes |
|---|---|---|
startCaptureSession(options?) |
Presents the full-screen capture flow. | Both platforms |
dismissCaptureSession() |
Programmatically dismisses the capture UI. | Both platforms |
uploadCapture(filePath, presignedUrl) |
Uploads the zip at filePath via HTTP PUT to presignedUrl. |
Both; see platform differences |
setupUploader() |
Resumes interrupted background uploads from a previous app session. | iOS only. On Android this is a documented no-op. |
| RN Event | When it fires | Payload |
|---|---|---|
onCaptureComplete |
Zip is ready on disk. | { archivePath: string } |
onStatusChange |
Capture state machine transitions. | { status: string, error?: string } |
onDismiss |
Capture UI is dismissed (user or programmatic). | {} |
onUploadProgress |
Upload bytes transferred. | { progress: number } (0.0–1.0) |
onUploadComplete |
Upload finished (success or failure). | { success: boolean } |