Roomio SDK for React Native

Scan a space from your own scanning screen. <RoomioScanView> shows the camera, the scan as it builds, the SDK's scanning guidance, and the buttons to complete or exit the scan; you start the scan and follow it through a RoomioScanSession.

Works in React Native 0.80 or later with the new architecture, with or without Expo (SDK 56 or later).

Install

npm install https://cdn.roomio.io/sdk/react-native/<version>/roomio-react-native-sdk-<version>.tgz

The package includes the iOS SDK. The Android SDK of the same version comes from the Maven repository at https://cdn.roomio.io/sdk/android/maven, which your app needs to list.

Requirements: iOS 17 or later; Android 7.0 (API 24) or later on an ARCore-supported arm64 phone. Scanning needs a real device.

Expo

Add the plugin, the iOS deployment target and expo-build-properties to your app config, then use a development build (npx expo run:ios, npx expo run:android or EAS Build). Expo Go cannot run the SDK.

{
  "expo": {
    "ios": { "deploymentTarget": "17.0" },
    "plugins": [
      ["@roomio/react-native-sdk", { "cameraPermission": "The camera is used to scan the space." }],
      ["expo-build-properties", { "android": { "buildArchs": ["arm64-v8a"] } }]
    ]
  }
}

The plugin adds the camera usage text and the Android SDK's repository, and stops prebuild if the deployment target is below 17. expo-build-properties builds Android for arm64 only.

React Native without Expo

  • iOS: add NSCameraUsageDescription to Info.plist, and set the deployment target to 17 in your Podfile and Xcode project. Then run pod install.
  • Android: add maven { url "https://cdn.roomio.io/sdk/android/maven"; content { includeGroup "io.captur3d" } } to allprojects.repositories in android/build.gradle, and set reactNativeArchitectures=arm64-v8a in android/gradle.properties.

Use

import { useEffect } from 'react';
import { StyleSheet, View } from 'react-native';
import { Roomio, RoomioScanView } from '@roomio/react-native-sdk';

Roomio.configure('roomio_pub_live_…');

const session = await Roomio.startScan();

function ScanScreen() {
  // Recording begins once the user is through the onboarding.
  useEffect(() => {
    session.start();
  }, []);
  return (
    <View style={{ flex: 1 }}>
      <RoomioScanView session={session} style={StyleSheet.absoluteFill} />
    </View>
  );
}

// When state.type is 'finished':
const bundle = await session.export();
session.close();

// When state.type is 'cancelled', the user exited the scan:
session.close();

API

Roomio.configure(publishableKey) Configure the SDK. Call once, first. If Roomio rejects the key, publishable_key_rejected shows in the device log; scanning still works
Roomio.version The SDK version, to quote to Roomio support
Roomio.flush() Send any waiting reports now, in the background. Does nothing while a scan is recording
Roomio.isSupported() supported, supported_needs_update or checking (Android), or unsupported. Offer scanning for anything but unsupported; the scan view handles the ARCore install
Roomio.startScan({ showsOnboarding }) Create a session. It isn't recording yet
Roomio.exportDiagnostics(scanId?) An encrypted diagnostics file for Roomio support
<RoomioScanView session /> The camera, scan, guidance, and the Complete scan and close buttons. One view per session
<RoomioScanView primaryColor secondaryColor /> Your own colours: primaryColor fills the main buttons, secondaryColor is their text and the fill of the others. Roomio's by default
useRoomioScanSession(session) { state, isShowingOnboarding, isShowingDialog }, re-rendering when they change. Hide your own controls while either is true. state.type is idle, starting, scanning (with tracking), paused, recovering, saving, finished, cancelled or failed (with error)
session.startPreview() Start the camera before recording. iOS only; Android starts it when the view shows, or once the onboarding ends
session.start() Start recording. Call it when you show the view; while the onboarding shows, recording begins once the user finishes or skips it
session.pause(), resume() Pause and resume the recording
session.stop() Finish recording, as the view's Complete scan button does. Rejects with not_ready in the first few seconds of a scan
session.export() The packaged scan, once the state is finished: { path, sizeBytes, scanId }. path is a plain file path (no file://) in the app's private storage, kept until you delete it. scanId can be null
session.close() Release the camera. Call when the user leaves the scan
session.addListener(listener) Tracking, progress, guidance and failure events: { type: 'trackingChanged' | 'progressUpdated' | 'guidanceChanged' | 'failed', … }. Returns a subscription with remove(). Subscribe before start(); past events aren't replayed

The scan pauses when the app goes to the background and resumes when it returns.

Errors

Promises reject with an Error carrying code, message, severity and isRetryable. code is the SDK's error code, for example permission_denied, not_configured, device_not_supported, not_ready or export_failed. A failure during the scan moves state to { type: 'failed', error }, with error carrying the same fields; the scan has stopped, so close the session.

severity is recoverable (the scan continues) or fatal (the scan has stopped). If isRetryable is true, offer a new scan, or on export_failed call export() again: the scan is kept. There's no cancel(): close() discards an unfinished scan.

On the web, importing the package is safe: isSupported() resolves unsupported and <RoomioScanView> renders nothing.

Roomio SDK 0.0.15