Mobile App Setup
The ScanPick mobile app is built with Expo SDK 55 (React Native 0.83). It serves as the warehouse floor scanner for pickers.
Development Setup
Section titled “Development Setup”Prerequisites
Section titled “Prerequisites”- Node.js 20+
- Expo CLI (
npx expo) - Android Emulator or iOS Simulator
- Physical device with Expo Go (for testing)
Start Development
Section titled “Start Development”cd mobilenpm installnpx expo start- Press
afor Android Emulator - Press
ifor iOS Simulator - Scan the QR code with Expo Go on a physical device
API URL Configuration
Section titled “API URL Configuration”The mobile app discovers the API URL from an environment variable.
For development, set API_BASE_URL in mobile/.env:
API_BASE_URL=http://10.0.2.2:500010.0.2.2is the Android Emulator’s alias for the host machine- Use your machine’s local IP for physical devices (e.g.,
http://192.168.1.100:5000) - In production, point to your ScanPick API instance
Key Implementation Details
Section titled “Key Implementation Details”SignalR Connection
Section titled “SignalR Connection”The mobile app uses @microsoft/signalr for real-time updates.
Critical: The polyfill react-native-url-polyfill/auto must be the first import
in the mobile entry point. This resolves a Hermes engine incompatibility with SignalR’s
use of URL.pathname.
// mobile/index.ts — FIRST importimport 'react-native-url-polyfill/auto';UUID Generation
Section titled “UUID Generation”Hermes does not support crypto.randomUUID(). The app uses a Math.random()-based
UUID v4 generator instead. Do not use crypto.randomUUID() or the uuid npm package.
// Internal UUID generator — no crypto dependencyfunction generateId(): string { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0; return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); });}Barcode Scanning
Section titled “Barcode Scanning”The app uses the device camera for barcode scanning. After a 3-second timeout without a scan, a “Type barcode” fallback button appears for manual entry.
Offline Support
Section titled “Offline Support”Scans queue locally in MMKV storage when the device is offline or the API is unreachable. The queue drains automatically when connectivity returns:
- Scans are stored with a client-generated UUID (idempotency key)
- Server deduplicates by idempotency key
- Failed scans are retried with a 1-second backoff
- Scans with exhausted retry budget are flagged as failed
Metro Cache
Section titled “Metro Cache”When modifying polyfill imports, always clear the Metro cache:
npx expo start -cThis prevents stale cache issues after import changes.
Building for Production
Section titled “Building for Production”Android APK/AAB
Section titled “Android APK/AAB”cd mobilenpx expo build:androidiOS IPA
Section titled “iOS IPA”cd mobilenpx expo build:iosApp Store Publishing
Section titled “App Store Publishing”See the Licensing & Renewals page for information about ScanPick licensing for mobile app distribution.