Advanced Topics

This page covers advanced Infinity Plugin features including UI configuration, native view integration, scan switching, User Corrected Results (UCR), event caching, and platform-specific considerations.

UI Configuration

The Infinity Plugin offers two approaches to customizing the scan view UI: ScanView Config Options for simple, built-in controls and UI Feedback Config for advanced, fully customizable overlays.

Prefer UI Feedback Config over ScanView Config Options whenever possible. It provides finer positioning control, uniform presentation across Android and iOS, and the ability to respond dynamically to scan feedback events.

ScanView Config Options

scanViewConfigOptions provides a set of pre-built UI controls that can be added to the scan view with minimal configuration. These are passed as a top-level JSON property alongside the scan start request.

  • rotateButton

  • defaultOrientation

  • toolbarTitle

  • segmentConfig

A button that toggles between portrait and landscape orientations when tapped. Positioned by alignment (corner of the screen) and optional pixel offset.

{
  "options": {
    "rotateButton": {
      "alignment": "top_right",
      "offset": { "x": -16, "y": 16 }
    }
  }
}

Sets the initial screen orientation when the scan view is presented. Values: portrait or landscape.

{
  "options": {
    "defaultOrientation": "landscape"
  }
}

Title shown on the toolbar with a back button. Fullscreen scanning only. Ignored when using a ContainerView (NativeView mode).

{
  "options": {
    "toolbarTitle": "Scan Document"
  }
}

A multi-mode segment control for switching between different scanning configurations (e.g., MRZ, Barcode, License Plate). Requires equal numbers of titles and viewConfigs.

{
  "options": {
    "segmentConfig": {
      "titles": ["MRZ", "Barcode", "License Plate"],
      "viewConfigs": ["mrz_config.json", "barcode_config.json", "license_plate_config.json"],
      "titleIndex": 0,
      "tintColor": "0099FF"
    }
  }
}
The viewConfigs entries reference ScanViewConfig JSON files in the assets folder, resolved relative to the scanViewConfigPath set in the WrapperSessionScanStartRequest.

For all available options and their properties, see the WrapperSessionScanViewConfigOptions schema reference.

UI Feedback Config

For more advanced UI customization, use the UI Feedback Config system. This allows you to define interactive overlay elements (labels, images) that respond to scan state changes and user interaction.

Key advantages over ScanView Config Options:

  • Fine-grained positioning: precise control over element placement, sizing, and layering

  • Cross-platform consistency: uniform rendering on both Android and iOS

  • Scan feedback integration: elements can react dynamically to scan events (e.g. insufficient lighting, incorrect distance from object)

  • Interactive elements: tappable elements emit events via onUIElementClicked

See UI Feedback Config for the full configuration guide, UIFeedback Config Elements for all available element types, and the UI Feedback Config schema reference.

Native View Integration

The Infinity Plugin supports two presentation modes for the scan view: full-screen and embedded (NativeView). Support varies by platform.

Feature Flutter React Native Cordova

Full-screen scanning

Embedded NativeView

Full-Screen Mode

In full-screen mode, calling requestScanStart launches a native Activity (Android) or ViewController (iOS) that takes over the entire screen. This is the simplest integration and works on all platforms.

Embedded NativeView Mode (Flutter & React Native)

In NativeView mode, the scan view is embedded directly in the app’s widget/component tree. This allows you to display scanning alongside other UI elements (e.g., a results list) and control the view’s size and position.

  • React Native

Use the AnylineNativeView component to embed the scan view:

import React, { Component } from 'react';
import { View, requireNativeComponent } from 'react-native';

// Register the native view component
const AnylineNativeView = requireNativeComponent('AnylineNativeView');

class ScanScreen extends Component {
  render() {
    return (
      <View style={{ flex: 1 }}>
        <AnylineNativeView
          style={{ flex: 1 }}
          viewId="scan-view-container-id"
        />
        {/* Add your custom UI elements here */}
      </View>
    );
  }
}

When AnylineNativeView is rendered in the component tree, scanning renders inside it. Remove it from the tree to use full-screen mode instead.

Scan Switching

The Infinity Plugin supports switching scan modes without stopping and restarting the scan session.

Two methods are available:

  • requestScanSwitchWithScanStartRequestParams: switches using a full WrapperSessionScanStartRequest, allowing you to change all scan parameters

  • requestScanSwitchWithScanViewConfigContentString: switches using only a raw ScanViewConfig JSON string, for simple configuration changes

Both methods are fire-and-forget: they do not return a response.

The correlationId parameter in scanViewInitializationParameters is an optional identifier you can set to group related scan operations in analytics and event exports.

  • React Native

Switch to a new scan mode using a full scan-start request. For example, to change the scan configuration, save result images to a directory, and set a workflow correlationId:

import { WrapperSessionScanResultCleanStrategyConfig } from 'anyline-ocr-react-native-module/AnylineInfinityPlugin';
import * as FileSystem from 'expo-file-system';

const resultPath = FileSystem.documentDirectory
  .replace(/^file:\/\//, '')
  .replace(/\/$/, '') + '/results/';

// newScanViewConfigJson: a JSON string containing the replacement ScanViewConfig
const switchRequest = {
  scanViewConfigContentString: newScanViewConfigJson,
  scanResultConfig: {
    cleanStrategy: WrapperSessionScanResultCleanStrategyConfig.CleanFolderOnStartScanning,
    imageContainer: {
      saved: {
        path: resultPath,
      },
    },
    imageParameters: {
      quality: 50,
      format: 'png',
    },
  },
  scanViewInitializationParameters: {
    correlationId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
  },
};
infinityPlugin.requestScanSwitchWithScanStartRequestParams(switchRequest);

Or switch using only a raw ScanViewConfig JSON string:

infinityPlugin.requestScanSwitchWithScanViewConfigContentString(
  newScanViewConfigJson,
);

User Corrected Results (UCR)

UCR allows you to submit corrections for scan results back to Anyline. This feedback loop helps improve scanning accuracy over time.

UCR is opt-in, and you decide how it is implemented in your app. Additionally, your Anyline License Key needs to have the relevant flag enabled for UCR. Please contact your CSM or Support for further information.

After receiving a scan result, you can present it to the user for verification. If the user corrects any fields, submit the corrected data via requestUCRReport. The request requires the blobKey from the original scan result, a unique identifier that links the correction to the specific scan event on the Anyline backend.

  • React Native

import {
  AnylineInfinityPlugin,
  WrapperSessionUcrReportResponseStatus,
} from 'anyline-ocr-react-native-module/AnylineInfinityPlugin';

// pluginResult: obtained from the onScanResults event stream (see Scan Result Handling)
// userCorrectedValue: the value corrected by the user after reviewing the scan result
const ucrRequest = {
  blobKey: pluginResult.blobKey,
  correctedResult: userCorrectedValue,
};

const ucrResponse = await infinityPlugin.requestUCRReport(ucrRequest);

if (ucrResponse.status === WrapperSessionUcrReportResponseStatus.UcrReportSucceeded) {
  console.log('UCR submitted:', ucrResponse.succeedInfo?.message);
} else {
  console.log('UCR failed:', ucrResponse.failInfo?.lastError);
}

Exporting Cached Events

Your contact person at Anyline may request you to supply a log archive to track usage statistics. The Anyline Infinity Plugin provides the requestExportCachedEvents method to export cached scan events into a ZIP archive on the device filesystem. The method returns a response containing the filesystem path to the generated archive.

Export of cached events ZIP generation can take up to several minutes depending on the number of recorded events.

After exporting, retrieve the archive from the device and send it to your contact person at Anyline, as agreed to beforehand.

  • React Native

import {
  AnylineInfinityPlugin,
  WrapperSessionExportCachedEventsResponseStatus,
} from 'anyline-ocr-react-native-module/AnylineInfinityPlugin';

const exportResponse = await infinityPlugin.requestExportCachedEvents();

if (exportResponse.status === WrapperSessionExportCachedEventsResponseStatus.ExportSucceeded) {
  const filePath = exportResponse.succeedInfo?.exportedFile;
  console.log('Events exported to:', filePath);
} else {
  console.log('Export failed:', exportResponse.failInfo?.lastError);
}

Platform-Specific Considerations

React Native

  • Event listeners return EmitterSubscription objects. Always call .remove() on cleanup (e.g., in useEffect cleanup or componentWillUnmount).

  • getPluginVersion() is synchronous (returns a string directly); all other methods return Promises

  • requestScanStop and switch methods are synchronous (void). They do not return Promises.

Error Handling

All methods that interact with the native SDK can fail. Handle errors appropriately:

React Native: Handle Promise rejections with try/catch in async functions or .catch(). Response objects include a failInfo property with error details.

try {
  const response = await infinityPlugin.requestScanStart(request);
  if (response.failInfo) {
    console.error('Scan ended with error:', response.failInfo.lastError);
  }
} catch (error) {
  console.error('Scan start failed:', error);
}

Common error scenarios:

  • Invalid or expired license key

  • Camera permission not granted

  • Invalid ScanViewConfig JSON

  • Calling scan methods before SDK initialization

Next Steps