Scandit Provider

Defined under the namespace Scandit.Datacapture.Core

ScanditProvider provides a DataCaptureContext and a single shared Camera to the scanning views rendered below it. Every scanning view must have a ScanditProvider above it in the component tree.

A provider is either a root or a nested provider, depending on whether another ScanditProvider already sits above it:

  • Root — creates the data capture context and the camera, and disposes both when it unmounts. licenseKey is required here.

  • Nested — reuses the context and camera of the root provider and applies its own frameSourceState, torchState, cameraPosition and cameraSettings to that shared camera. licenseKey, settings and options are ignored on a nested provider, and a warning is logged if they are set.

Place the root provider above your navigation container, so that the context and camera survive navigation between screens.

<ScanditProvider licenseKey={LICENSE_KEY}>
  <NavigationContainer>
    {/* screens */}
  </NavigationContainer>
</ScanditProvider>

Camera ownership

Exactly one scanning view holds the camera at any moment. Read this before adding a second scanning screen — it is not visible from the view signatures.

  • The most recent view to render takes ownership. When a view becomes active it claims the camera, and that claim supersedes the previous owner.

  • Calls from a superseded owner are ignored. A view that has lost the claim cannot turn the camera on, change the torch, or switch position. Its calls are accepted and do nothing, rather than failing.

  • Between screens the camera drops to FrameSourceState.Standby. The sensor is released and no frames are produced, but the capture session stays alive, so resuming on the next screen is near-instant and the preview does not blink. If no screen resumes, the shutdown completes natively a short time later.

Two scanning screens therefore need no coordination. Each renders its view, and the provider resolves the hand-off.

Pass a ScanditNavigationProp and the view runs while its screen is focused and the app is in the foreground:

function ScanScreen({ navigation }) {
  return (
    <BarcodeCaptureAioView
      navigation={navigation}
      didScan={(barcodes, session, getFrameData) => { /* ... */ }}
    />
  );
}

Without one, a view still follows the app’s foreground state, but not screen focus. Use disabled to keep a view off, and appStateHandlingDisabled to take over the foreground handling yourself.

Note

A view’s claim also follows its native view entering and leaving the window, so tab switches and reveals work with any navigation library, or none.

Note

The view adds and removes its DataCaptureMode on the DataCaptureContext for you. Never call DataCaptureContext.addMode() for a scanning view.

Configuring the camera

ScanditProviderProps.torchState, ScanditProviderProps.cameraPosition and ScanditProviderProps.cameraSettings configure the shared Camera for every view that uses it. To scope them to one screen, wrap that screen in a nested ScanditProvider:

function ScanScreen({ navigation }) {
  const [torch, setTorch] = useState(Scandit.TorchState.Off);

  return (
    <ScanditProvider torchState={torch} cameraPosition={Scandit.CameraPosition.WorldFacing}>
      <BarcodeCaptureAioView navigation={navigation} />
      <Button title="Toggle torch" onPress={() => setTorch(next(torch))} />
    </ScanditProvider>
  );
}

cameraSettings is the only way to set resolution, focus and zoom, because the provider owns the camera and the scanning views have none of their own. Build a CameraSettings and pass it in:

const cameraSettings = new Scandit.CameraSettings();
cameraSettings.preferredResolution = Scandit.VideoResolution.FullHD;
cameraSettings.zoomFactor = 2;

<ScanditProvider cameraSettings={cameraSettings}>
  <BarcodeCaptureAioView navigation={navigation} />
</ScanditProvider>

See CameraSettings.preferredResolution, CameraSettings.zoomFactor and CameraSettings.focusRange for what can be set.

Values set on a nested provider are applied to the shared camera and are not reverted when that provider unmounts. The last provider to write a value wins.

Note

These props do not reach SparkScanAioView. That view drives its own native camera, so the provider camera does not render for it. Set its initial state through its sparkScanViewSettings prop, using SparkScanViewSettings.defaultTorchState and SparkScanViewSettings.defaultCameraPosition, and let the user change it at runtime with the view’s own torchControlVisible and cameraSwitchButtonVisible props.

ScanditProvider

ScanditProvider
class ScanditProvider

Added in version 8.7.0

A React component that provides a DataCaptureContext and a shared Camera to the scanning views below it. Takes ScanditProviderProps. See Camera ownership for how the shared camera moves between views.

ScanditProviderProps
interface ScanditProviderProps

Added in version 8.7.0

The props of ScanditProvider.

licenseKey
licenseKey?: string

Added in version 8.7.0

The Scandit license key. Required on the root provider; a root provider without it throws. Ignored on a nested provider.

options
options?: DataCaptureContextCreationOptions

Added in version 8.7.0

Options applied when the DataCaptureContext is created. Used by the root provider only, and only at creation — later changes have no effect.

settings
settings?: DataCaptureContextSettings

Added in version 8.7.0

Settings applied to the DataCaptureContext. Used by the root provider only.

frameSourceState
frameSourceState?: FrameSourceState

Added in version 8.7.0

Claims the camera for as long as this is FrameSourceState.On, without a scanning view being present. Any other value, including leaving it unset, means the provider does not claim the camera and the views below it drive it instead. A view that becomes active while this is FrameSourceState.On supersedes the provider’s claim.

torchState
torchState?: TorchState

Added in version 8.7.0

The torch state of the shared camera. On the root provider, leaving it unset applies TorchState.Off. On a nested provider it is set-only: leaving it unset leaves the torch as the last writer left it. Does not reach SparkScanAioView — see Configuring the camera.

cameraPosition
cameraPosition?: CameraPosition

Added in version 8.7.0

The position of the shared camera. On the root provider, leaving it unset applies CameraPosition.WorldFacing. On a nested provider it is set-only: leaving it unset leaves the position as the last writer left it. Changing it recreates the camera. Does not reach SparkScanAioView — see Configuring the camera.

cameraSettings
cameraSettings?: CameraSettings | null

Added in version 8.7.0

Capture settings — see CameraSettings — for the shared camera. The provider owns the camera, so this is the only way to configure it: a scanning view has no camera of its own to apply them to.

Compared structurally, so an inline new CameraSettings() does not need useMemo. Set-only on the root provider as well as on nested ones — no default is applied, so leaving it unset or passing null leaves the camera as it is rather than restoring device defaults, and a value set by a nested provider outlives that provider’s unmount.

onError
onError?: (error: unknown) => void

Added in version 8.7.0

Called when an asynchronous camera operation fails, for example a frame source state transition. Failures are logged regardless; this exists so that they can also be surfaced in the app or sent to telemetry. Honored on the root provider only, since it owns the camera.

children
children: any

Added in version 8.7.0

The React node tree that has access to this provider’s context and camera.

Hooks

useIsForeground()
function useIsForeground(): boolean

Added in version 8.7.0

Returns whether the app is currently in the foreground, and re-renders the calling component when that changes.

The scanning views do not need this: each one already follows the app’s foreground state on its own, and stops scanning when the app is backgrounded. Use this hook when your own components need the same signal — for example to hide a prompt while the app is in the background, or to drive a view’s disabled prop by hand after opting out with appStateHandlingDisabled.

const isForeground = useIsForeground();

return isForeground ? <ScanPrompt /> : null;
useCameraPermission()
function useCameraPermission(): CameraPermissionResult

Added in version 8.7.0

Reports the camera permission status and requests it, re-rendering the calling component when the status changes.

const { hasPermission, requestPermission } = useCameraPermission();

if (!hasPermission) {
  return <Button onPress={requestPermission} title="Grant camera access" />;
}

What the hook can observe differs by platform:

  • Android — CameraPermissionResult.requestPermission shows the system prompt and reports the outcome, including denied and restricted. The status is re-read whenever the app returns to the foreground, so a change made in Settings is picked up — but that refresh only distinguishes granted from not granted, so denied and restricted are not preserved across it and fall back to not-determined.

  • iOS — limited. iOS presents its permission dialog automatically the first time the camera is accessed and does not expose the status to JavaScript, so CameraPermissionResult.permissionStatus starts as not-determined and moves to granted once CameraPermissionResult.requestPermission has been called, whether or not the user agreed. A denial cannot be detected here; treat the camera start as the authoritative signal and handle it through the view’s onError.

useScanditContext(licenseKey, options)
function useScanditContext(licenseKey: string,
        options?: UseScanditContextOptions): DataCaptureContext

Added in version 8.7.0

Returns the DataCaptureContext singleton, initializing it on the first call. The context is keyed on the license key, so calling this from several components with the same key returns the same context.

Use it when a component needs the context directly. A component tree under a ScanditProvider does not need this hook — the provider already owns the context and hands it to the views below it.

const settings = useMemo(() => new DataCaptureContextSettings(), []);
const context = useScanditContext('YOUR_LICENSE_KEY', { settings });

Types

CameraPermissionResult
interface CameraPermissionResult

Added in version 8.7.0

The value returned by useCameraPermission().

hasPermission
hasPermission: boolean

Added in version 8.7.0

Whether camera access is currently granted. True exactly when permissionStatus is granted.

permissionStatus
permissionStatus: string

Added in version 8.7.0

The current permission status, typed as PermissionStatus — a union of four string values:

granted

Camera access has been granted.

denied

Camera access has been refused. Android only; iOS cannot report a denial to JavaScript.

not-determined

Camera access has not been decided yet. Also the initial value on iOS.

restricted

Camera access has been refused and the system will not prompt again. Android only, corresponding to NEVER_ASK_AGAIN.

requestPermission
requestPermission: () => Promise<boolean>

Added in version 8.7.0

Requests camera access and resolves to whether it was granted. On Android this shows the system prompt. On iOS it cannot drive the prompt and resolves to true optimistically — see useCameraPermission().

UseScanditContextOptions
interface UseScanditContextOptions

Added in version 8.7.0

The options accepted by useScanditContext().

settings
settings?: DataCaptureContextSettings

Added in version 8.7.0

Applied on the first call, then re-applied through DataCaptureContext.applySettings() whenever a different instance is passed. Build the instance once, or memoize it — passing a new instance on every render re-applies the settings on every render.

creationOptions
creationOptions?: DataCaptureContextCreationOptions

Added in version 8.7.0

Applied once, when the context is created natively. Later changes are ignored.

ScanditNavigationProp
interface ScanditNavigationProp

Added in version 8.7.0

The type of the navigation prop on the scanning views. A view uses it to enable itself when its screen is focused and disable itself when the screen is blurred.

React Navigation’s navigation object satisfies this interface, so it can be passed straight through. Any other source of focus events can implement the same method.

function ScanScreen({ navigation }) {
  return <BarcodeCaptureAioView navigation={navigation} />;
}
addListener
addListener?: any

Added in version 8.7.0

Subscribes to a screen event and returns the function that cancels the subscription. It is optional: a view given no navigation prop simply does not react to focus changes.

addListener?(type: 'focus' | 'blur', callback: () => void): () => void
EnableDisableHandle
interface EnableDisableHandle

Added in version 8.7.0

Imperative control over whether a scanning view is scanning. Every scanning view’s ref handle carries these two methods, so they are available on any of them.

Reach for this only when the declarative path does not fit. Normally a view is driven by its ScanditNavigationProp and its disabled prop, which handle screen focus and app background automatically — see Camera ownership.

const ref = useRef(null);

<BarcodeCaptureAioView ref={ref} navigation={navigation} />
<Button title="Pause" onPress={() => ref.current?.disable()} />
enable()
enable(): Promise<void>

Added in version 8.7.0

Starts scanning now: enables the mode and claims the camera. Claiming the camera supersedes whichever view held it — see Camera ownership.

disable()
disable(): Promise<void>

Added in version 8.7.0

Stops scanning now: disables the mode and releases the camera.