A comprehensive React Native SDK for NFC-based device control and communication
npm install je_nfc_sdkA comprehensive React Native SDK for NFC-based device control and communication, specifically designed for irrigation control systems and IoT devices.
- Complete NFC Control Interface: Full-featured control screen with solenoid management, scheduling, time synchronization, and sensor data
- Modular Components: Reusable NFC operation cards and UI components
- Custom Hooks: React hooks for NFC operations management
- Frame Server: Advanced NFC frame handling with ISO 7816 support
- Operation State Management: Comprehensive state machine for NFC operations
- Customizable UI: Theme support, custom icons, and configurable categories
- TypeScript Support: Full TypeScript definitions for type safety
- Logging Service: Built-in logging and debugging capabilities
Since this is a local SDK, you can import it directly in your React Native project:
``typescript`
import {
ControlScreen,
NfcOperationCard,
useNfcOperations,
LoggerService,
FrameServer
} from './je_nfc_sdk';
Make sure your project has these peer dependencies installed:
`json`
{
"react": ">=18.0.0",
"react-native": ">=0.71.0",
"react-native-nfc-manager": ">=3.11.0",
"react-native-safe-area-context": ">=5.4.0",
"react-native-screens": ">=4.10.0",
"react-native-linear-gradient": ">=2.8.0",
"react-native-vector-icons": ">=10.0.0",
"@react-native-picker/picker": ">=2.11.0",
"@react-native-community/datetimepicker": ">=8.3.0"
}
`typescript
import React from 'react';
import { ControlScreen } from './je_nfc_sdk';
const MyApp = () => {
const translate = (key: string) => {
// Your translation logic here
return key;
};
const handleTagConnected = (tagInfo: any) => {
console.log('Tag connected:', tagInfo);
};
const handleOperationComplete = (operationType: string, result: any) => {
console.log('Operation completed:', operationType, result);
};
const handleError = (error: string) => {
console.error('NFC Error:', error);
};
return (
onTagConnected={handleTagConnected}
onOperationComplete={handleOperationComplete}
onError={handleError}
showMenu={true}
categories={['connection', 'solenoid', 'time', 'pressure']}
theme="light"
enableScheduling={true}
enableSensorData={true}
/>
);
};
export default MyApp;
`
`typescript
import React from 'react';
import { View } from 'react-native';
import { NfcOperationCard, useNfcOperations } from './je_nfc_sdk';
const MyCustomScreen = () => {
const operationConfigs = {
solenoid_1: {
writeCmd: 0x13,
writeSubCmd: 0x10,
readCmd: 0x12,
writeApdu: [0x11],
readApdu: [0x00],
displayName: 'Solenoid 1',
processingMessage: 'Processing solenoid operation...',
icon: '🎚️'
}
};
const {
operations,
handleOperation,
isScanning,
connectToTag
} = useNfcOperations({
operationConfigs,
onOperationComplete: (type, result) => console.log(type, result),
onError: (error) => console.error(error)
});
return (
config={operationConfigs.solenoid_1}
operation={operations.solenoid_1}
onPress={() => handleOperation('solenoid_1')}
disabled={isScanning}
/>
);
};
`
`typescript
import { FrameServer, LoggerService } from './je_nfc_sdk';
const performCustomOperation = async () => {
try {
// Write data to device
const writeResult = await FrameServer.writeData(0x13, 0x10, [0x11]);
if (writeResult.success) {
LoggerService.success('Write operation successful');
// Read data from device
const readResult = await FrameServer.readReq(0x12, 0x10, [0x00]);
if (readResult.success && readResult.data) {
LoggerService.success('Read operation successful');
console.log('Device response:', readResult.data);
}
}
} catch (error) {
LoggerService.error(Operation failed: ${error});`
}
};
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| translate | (key: string) => string | (key) => key | Translation function for internationalization |operationConfigs
| | Record | {} | Custom operation configurations |icons
| | Record | {} | Custom icons for categories |onTagConnected
| | (tagInfo: any) => void | undefined | Callback when NFC tag is connected |onOperationComplete
| | (operationType: string, result: any) => void | undefined | Callback when operation completes |onError
| | (error: string) => void | undefined | Error callback |initialSolenoidStates
| | Record | {1: false, 2: false, 3: false, 4: false} | Initial solenoid states |initialSchedules
| | Schedule[] | [] | Initial schedules |showMenu
| | boolean | true | Whether to show the side menu |categories
| | string[] | ['connection', 'solenoid', 'schedule', 'time', 'pressure', 'waterflow'] | Available categories |theme
| | 'light' \| 'dark' | 'light' | UI theme |enableScheduling
| | boolean | true | Enable scheduling features |enableSensorData
| | boolean | true | Enable sensor data features |enableTesting
| | boolean | false | Enable testing features |
`typescript`
interface OperationConfig {
writeCmd: number; // Write command ID
writeSubCmd: number; // Write sub-command ID
readCmd: number; // Read command ID
writeApdu: number[]; // Write APDU data
readApdu: number[]; // Read APDU data
displayName: string; // Human-readable name
processingMessage: string; // Message shown during processing
icon: string; // Icon or emoji
}
`typescript`
interface OperationStatus {
state: OperationState;
lastOperation: {
type: 'WRITE' | 'READ' | null;
status: 'SUCCESS' | 'FAILED' | 'COMPLETED' | null;
timestamp: number | null;
};
processingBit: number;
data?: string;
resetRequested?: boolean;
processingStartTime?: number;
timer?: {
startTime: number;
currentValue: number;
isRunning: boolean;
};
}
The useNfcOperations hook provides a complete interface for managing NFC operations:
`typescript`
const {
operations, // Current operation states
isScanning, // Whether NFC is currently scanning
isTagConnected, // Whether NFC tag is connected
handleOperation, // Execute an operation
connectToTag, // Connect to NFC tag
resetOperation, // Reset an operation state
updateOperationStatus, // Update operation status
getOperationButtonText, // Get button text for operation
getStatusColor, // Get status color for operation
transceiveWithTimeout // Send APDU with timeout
} = useNfcOperations({
operationConfigs,
onOperationComplete,
onError,
translate
});
The FrameServer provides low-level NFC communication:
- writeData(commandId, idIndex, data) - Write data to NFC devicereadReq(commandId, idIndex, parameters)
- - Read data from NFC devicecreateSendFrame(commandId, idIndex, data, instruction)
- - Create NFC frameparseFrame(frameData)
- - Parse received NFC frametransceiveWithTimeout(apduCommand, timeout)
- - Send APDU with timeouthexFrameToDecimal(hexFrame, dataLength)
- - Convert hex frame to decimal
The LoggerService provides logging capabilities:
- log(message, level, category) - Log a messageinfo(message, category)
- - Log info messagewarning(message, category)
- - Log warning messageerror(message, category)
- - Log error messagesuccess(message, category)
- - Log success messagegetLogs()
- - Get all logsclearLogs()
- - Clear all logssubscribe(callback)
- - Subscribe to log updates
The SDK uses a state machine for operation management:
- IDLE - Operation is ready to startWRITE_PENDING
- - Write operation in progressREAD_READY
- - Ready to read after successful writeREAD_PENDING
- - Read operation in progressPROCESSING
- - Device is processing the operationERROR
- - Operation failedREAD_READY_WRITE
- - Ready for next write operationREAD_READY_READ
- - Ready for status read
`typescript
const customOperations = {
my_custom_operation: {
writeCmd: 0x20,
writeSubCmd: 0x01,
readCmd: 0x21,
writeApdu: [0x01, 0x02, 0x03],
readApdu: [0x00],
displayName: 'My Custom Operation',
processingMessage: 'Processing custom operation...',
icon: '⚙️'
}
};
`
`typescript
const customIcons = {
connection: require('./assets/my-connection-icon.png'),
solenoid: require('./assets/my-solenoid-icon.png'),
};
`
`typescript`
// ... other props
/>
The SDK provides comprehensive error handling:
`typescript
const handleError = (error: string) => {
// Log error
LoggerService.error(error);
// Show user-friendly message
Alert.alert('Operation Failed', error);
// Send to crash reporting service
crashlytics().recordError(new Error(error));
};
`
Enable detailed logging for debugging:
`typescript
import { LoggerService } from './je_nfc_sdk';
// Subscribe to all logs
const unsubscribe = LoggerService.subscribe((logs) => {
console.log('All logs:', logs);
});
// Log custom messages
LoggerService.info('Custom debug message', 'system');
LoggerService.error('Custom error message', 'connection');
// Clean up
unsubscribe();
`
1. Always handle errors: Provide error callbacks to handle NFC communication failures
2. Use translations: Implement proper internationalization with the translate prop
3. Customize operations: Define your own operation configurations for specific device protocols
4. Monitor state: Subscribe to operation state changes for UI updates
5. Clean up resources: Ensure NFC resources are properly cleaned up when components unmount
6. Test thoroughly: Test NFC operations on real devices with actual NFC tags
1. NFC not working: Ensure NFC is enabled on the device and proper permissions are granted
2. Connection timeouts: Adjust timeout values in transceiveWithTimeout calls
3. Frame parsing errors: Check that your operation configurations match the device protocol
4. State management issues: Use the provided hooks and don't modify operation states directly
Enable debug mode for detailed logging:
`typescript
// Enable verbose logging
LoggerService.log('Debug mode enabled', 'info', 'system');
// Monitor all NFC operations
const { operations } = useNfcOperations({
operationConfigs,
onOperationComplete: (type, result) => {
LoggerService.success(Operation ${type} completed: ${JSON.stringify(result)});Operation failed: ${error}
},
onError: (error) => {
LoggerService.error();``
}
});
MIT License - see LICENSE file for details.
For support and questions, please refer to the project documentation or create an issue in the project repository.