Camera scanning with SocketCam¶
Support¶
The React Native CaptureSDK has support for both SocketCam C820 and C860.
Requirements¶
In order to use SocketCam in your React Native app, you will need to install or upgrade the React Native CaptureSDK to version 1.4 or higher.
iOS Requirements
You will need to update pods because in version 1.4 we updated the iOS SDK version from 1.3.34 to 1.6.39.
You may need to use pod install --repo-update
. Doing a regular pod install
might result in an error like the one below.
[!] CocoaPods could not find compatible versions for pod "CaptureSDK":
In Podfile:
react-native-capture (from `../node_modules/react-native-capture`) was resolved to 1.3.37, which depends on
CaptureSDK (~> 1.6.39)
In your Info.plist, you need to add the key to allow access to the camera. Add the below code to the bottom of your dict tag.
<key>NSCameraUsageDescription</key>
<string>Need to enable camera access for SocketCam products such as C820</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
Android Requirements
In AndroidManifest.xml you will need to add the below code.
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<meta-data android:name="com.socketmobile.capture.APP_KEY" android:value="{YOUR_APP_KEY}"/>
<meta-data android:name="com.socketmobile.capture.DEVELOPER_ID" android:value="{YOUR_DEVELOPER_ID}"/>
Using SocketCam C820¶
Once you have all of the changes above, you can start using SocketCam in your React Native App.
SocketCamViewContainer¶
In order to use SocketCam in your app, you will need to import the new SocketCamViewContainer
component provided by our CaptureSDK. This component is a container that contains logic, interfaces and variables for the below items that the developer is no longer required to do on their own.
Starting the SocketCam extension (for Android).
Checking whether or not SocketCam is enabled.
Setting the trigger property on the SocketCam device.
The SocketCam trigger options.
Now all the developer needs to is import the SocketCamViewContainer
and provide a few props that are required by the component. Below is an example of the new SocketCamViewContainer
component.
<SocketCamViewContainer
openSocketCamView={openSocketCamView}
handleUpdateSocketCamEnabled={handleUpdateSocketCamEnabled}
clientOrDeviceHandle={clientOrDeviceHandle}
triggerType={triggerType}
socketCamCapture={socketCamCapture}
socketCamDevice={socketCamDevice}
myLogger={myLogger}
handleSetStatus={handleSetStatus}
handleSetSocketCamExtensionStatus={
handleSetSocketCamExtensionStatus
}
/>
Required Props
Below are the required props for SocketCamViewContainer
.
clientOrDeviceHandle: number;
triggerType: number;
openSocketCamView: boolean;
socketCamCapture: CaptureRn;
socketCamDevice: CaptureDeviceInfo;
handleSetSocketCamEnabled: Function;
The clientOrDeviceHandle
, socketCamDevice
and socketCamCapture
are the same as they’ve always been. The triggerType
, once used for UI purposes in an example app is now required in order for the SocketCamViewContainer
to be able to set the trigger property when the view component loads. The button options for available trigger types for SocketCam are provided by the React Native CaptureSDK CaptureHelper
class (more info).
static SocketCamTriggerOptions: SocketCamTriggerButtonData[] = [
{ label: 'Start', value: `${Trigger.Start}` },
{ label: 'Continuous Scan', value: `${Trigger.ContinuousScan}` },
];
To use them, you can simply import them with your other react-native-capture
, as seen below.
import {
CaptureRn,
Trigger,
type CaptureDeviceInfo,
CaptureHelper,
} from 'react-native-capture';
const {SocketCamTriggerOptions} = CaptureHelper; // alternatively you can use CaptureHelper.SocketCamTriggerOptions
The next prop, handleSetSocketCamEnabled
is a required method that you provide in order for our helper functions to be able to update your app or component state to determine that SocketCam is enabled (SocketCam is enabled by default).
See an example below.
const [socketCamEnabled, setSocketCamEnabled] = useState<number>(1);
const handleSetSocketCamEnabled = (stat: number) => {
setSocketCamEnabled(stat);
};
The last required prop is openSocketCamView
. This one is straight forward: the prop that determines whether or not SocketCam should be opened or not!
Optional Props¶
Below are the optional props that can be accepted by SocketCamViewContainer
.
myLogger?: SocketLogger;
handleSetStatus?: Function;
handleSetSocketCamExtensionStatus?: Function;
socketCamCustomModalStyle?: SocketCamModalStyleProps;
socketCamCustomStyle?: StyleProp<ViewStyle>;
androidSocketCamCustomView?: React.ReactElement;
The myLogger
prop is the same as it’s always been: the (optional) SocketLogger
instance you create to help log results from capture events. As it is optional in your React Native application as a whole, it is optional in this React Native CaptureSDK component as well.
The handleSetStatus
and handleSetSocketCamExtensionStatus
props are similar methods that serve different purposes.
Note
The props socketCamCustomModalStyle
, socketCamCustomStyle
, and androidSocketCamCustomView
are related to creating a custom view for SocketCam in your React Native application. You can read more about this latest feaure in the docs here.
Also, socketCamDevice
can technically be null
or undefined
at first because, depending on the platform, SocketCamViewContainer
will need to start the SocketCam extension before looking for the regular SocketCam device arrival. However, it will eventually need to be defined to actually open SocketCam. This can be done in the DeviceArrival event in your onCaptureEvent method. While socketCamDevice
can technically be undefined
or null
, you will still need to explicitly name it as a prop, or else TypeScript will throw an error.
Differentiating SocketCam from other devices¶
It is recommended in the UI to save the capture instance that is tied to SocketCam separately from other device capture instances as to avoid get/set property and usage conflicts. You can differentiate a SocketCam device from another device, such as a D740, by checking the device type in the device arrival event.
See the below code from an onCaptureEvent
callback. There is a section where we explicitly check for and set a SocketCam device-specified with the comment // check for SocketCam device type
.
const onCaptureEvent = (e: CaptureEvent<any>, handle: number) => {
if (!e) {
return;
}
let devs: CaptureDeviceInfo[] = [...stateRef.current.devices];
switch (e.id) {
case CaptureEventIds.DeviceArrival:
const newDevice = new CaptureRn();
openDeviceHelper(newDevice, e, false);
break;
// OTHER EVENT CASES
}
}
const genDevice = (
dev: CaptureRn,
guid: String,
name: String,
type: number,
) => {
return {
guid,
name,
type,
handle: dev.clientOrDeviceHandle,
devCapture: dev,
} as CaptureDeviceInfo;
};
const openDeviceHelper = (
dev: CaptureRn,
e: CaptureEvent<any>,
isManager: boolean,
) => {
let {name, guid, type} = e.value;
let loggedOption = isManager ? 'device manager' : 'device';
dev
.openDevice(guid, capture)
.then((result: number) => {
myLogger.log(`opening a ${loggedOption} returns: `, `${result}`);
setStatus(`result of opening ${name} : ${result}`);
let myMap = {...stateRef.current.deviceGuidMap};
if (!myMap[guid] && !isManager) {
let device = genDevice(dev, guid, name, type);
let devs = [...stateRef.current.devices, device];
setDevices(devs);
myMap[guid] = '1';
setDeviceGuidMap(myMap);
}
if (!isManager) {
// check for SocketCam device type
if (SocketCamTypes.indexOf(e.value.type) > -1) {
let device = genDevice(dev, guid, name, type);
setSocketCamDevice(device);
} else {
setDeviceCapture(dev);
}
} else {
setBleDeviceManagerCapture(dev);
getFavorite(dev);
}
})
.catch((res: JRpcError) => {
let {error} = res;
const {code, message} = error;
myLogger.error(resToString(error));
setStatus(`error opening a device: ${code} \n ${message}}`);
});
};