SingleEntryRN is a React Native sample app demonstrating how to integrate the Socket Mobile React Native Capture SDK (react-native-capture v2.x).
It shows how to:
- Receive decoded barcode/NFC data from Socket Mobile devices
- Discover and connect Bluetooth LE and Classic devices
- Use SocketCam (camera-based scanning) on both iOS and Android
- Read device properties (battery level, firmware version, friendly name)
- Configure symbologies and trigger modes
- React Native 0.83+
- Node 18+
react-native-capture^2.0.11
git clone git@github.com:socketmobile/singleentry-rn.git
cd singleentry-rnUsing npm:
npm installUsing yarn:
yarn installThen set up the iOS portion:
cd ios
pod installThe Socket Mobile Companion app must be installed on the Android device. It hosts the service used for connecting to scanners.
Download it from the Google Play Store.
If Socket Mobile Companion is not installed, helper.open() will return error code -27 (ESKT_UNABLEOPENDEVICE).
The easiest way to connect a Socket Mobile device on iOS is by using the Socket Mobile Companion app from the App Store.
The Capture SDK requires your app to be registered on the Socket Mobile Developer Portal.
You will need three credentials:
| Credential | Description |
|---|---|
developerId | UUID returned during developer registration |
appId | Platform-prefixed app identifier (e.g. ios:com.mycompany.myapp) |
appKey | Generated when you register your app on the portal |
Note: The application ID is case sensitive.
Define them as an AppInfoRn object with platform-specific values:
import{typeAppInfoRn}from'react-native-capture';constappInfo: AppInfoRn={appIdIos: 'ios:com.mycompany.myapp',appKeyIos: 'MC0C...',appIdAndroid: 'android:com.mycompany.myapp',appKeyAndroid: 'MC0C...',developerId: 'your-developer-id-uuid',};The v2.x SDK introduces CaptureHelper, an instance-based lifecycle manager that replaces the older CaptureRn + manual event handling pattern. You create a single instance with declarative callbacks, then call open() / close():
import{CaptureHelper,typeCaptureHelperDevice,typeDecodedData}from'react-native-capture';consthelper=newCaptureHelper({
appInfo,onDeviceArrival: (device: CaptureHelperDevice)=>{// A Socket Mobile device has connectedconsole.log(`Connected: ${device.name}`);},onDeviceRemoval: (device: CaptureHelperDevice)=>{// A Socket Mobile device has disconnectedconsole.log(`Disconnected: ${device.name}`);},onDecodedData: (data: DecodedData,device: CaptureHelperDevice)=>{// A barcode or NFC tag was scannedconsttext=String.fromCharCode(...(data.dataasnumber[]));console.log(`Scanned from ${device.name}: ${text}`);},onError: ({ code, message })=>{console.error(`Capture error ${code}: ${message}`);},});// Open the SDK (typically in a useEffect)awaithelper.open();// Close when done (cleanup)awaithelper.close();In a React component, this looks like:
useEffect(()=>{consthelper=newCaptureHelper({ appInfo, onDeviceArrival, onDecodedData,/* ... */});helper.open().then(()=>setStatus('Capture open'));return()=>{helper.close().catch(()=>{});};},[]);| Callback | Description |
|---|---|
onDeviceArrival(device) | Device connected |
onDeviceRemoval(device) | Device disconnected |
onDecodedData(data, device) | Barcode or NFC data scanned |
onSocketCamCanceled() | User closed the SocketCam camera view |
onDiscoveredDevice(device) | BLE device found during discovery |
onDiscoveryEnd() | Bluetooth discovery completed |
onBatteryLevel(level, device) | Battery level notification (0-100) |
onError({ code, message }) | An error occurred |
BLE devices (e.g. S721) require a manual discovery and connection flow, unlike Classic Bluetooth devices which pair at the OS level:
import{BluetoothDiscoveryMode,typeDiscoveredDeviceInfo}from'react-native-capture';// Start BLE discovery — results arrive via onDiscoveredDevice callbackawaithelper.addBluetoothDevice(BluetoothDiscoveryMode.BluetoothLowEnergy);// When the user selects a discovered device, connect itawaithelper.connectDiscoveredDevice(discoveredDevice);// To disconnect a BLE device laterawaithelper.removeBleDevice(device);Classic Bluetooth discovery is also available:
awaithelper.addBluetoothDevice(BluetoothDiscoveryMode.BluetoothClassic);Connected devices arrive as CaptureHelperDevice objects with typed methods:
// Read device propertiesconstfriendlyName=awaitdevice.getFriendlyName();constfirmware=awaitdevice.getFirmwareVersion();constbattery=awaitdevice.getBatteryLevel();// Set device propertiesawaitdevice.setFriendlyName('My Scanner');awaitdevice.setTrigger(Trigger.Start);// Configure symbologiesawaitdevice.setDataSource(CaptureDataSourceID.SymbologyQRCode,CaptureDataSourceStatus.Enable);SocketCam lets users scan barcodes using the device camera. Enable it through the helper:
awaithelper.setSocketCamEnabled(true);Then use the SocketCamViewContainer component to display the camera UI. Access the underlying CaptureRn instance via helper.rootCapture:
import{SocketCamViewContainer,Trigger}from'react-native-capture';constrootCapture=helper.rootCapture;<SocketCamViewContaineropenSocketCamView={showCamera}socketCamCapture={rootCapture}socketCamDevice={socketCamDevice}clientOrDeviceHandle={rootCapture?.clientOrDeviceHandle}triggerType={Trigger.Start}handleSetSocketCamEnabled={setSocketCamEnabled}handleSetStatus={setStatus}handleSetSocketCamExtensionStatus={setExtStatus}/>Android note: Mount
SocketCamViewContaineras soon asrootCaptureis available (before enabling SocketCam) so the extension process starts. Without this,setSocketCamEnabledmay return error-32(ESKT_NOTAVAILABLE).
| File | Description |
|---|---|
src/App.tsx | Main component — opens CaptureHelper, manages state |
src/components/MainView.tsx | Device list, BLE/Classic discovery, SocketCam toggle |
src/components/DeviceFeatures.tsx | Feature menu for a selected device |
src/components/SetTrigger.tsx | Trigger modes (start, stop, continuous) and SocketCam camera views |
src/components/Symbologies.tsx | Enable/disable barcode symbologies and NFC tag types |
src/components/FriendlyName.tsx | Get/set the device friendly name |
src/components/BatteryLevel.tsx | Read battery level and power state |
src/components/FirmwareVersion.tsx | Read firmware version and build date |
Make sure Metro is running before launching:
yarn startThen in a separate terminal:
yarn ios
# or
yarn androidYou can also run the app through Xcode or Android Studio.
To allow the Android device to reach the Metro bundler:
adb reverse tcp:8081 tcp:8081