You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.2 KiB
7.2 KiB
QR Code Implementation Guide
Overview
This document describes the QR code scanning and generation implementation in the TimeSafari application. The system uses a platform-agnostic design with specific implementations for web and mobile platforms.
Architecture
Directory Structure
src/
├── services/
│ └── QRScanner/
│ ├── types.ts # Core interfaces and types
│ ├── QRScannerFactory.ts # Factory for creating scanner instances
│ ├── CapacitorQRScanner.ts # Mobile implementation using MLKit
│ ├── WebInlineQRScanner.ts # Web implementation using MediaDevices API
│ └── interfaces.ts # Additional interfaces
├── components/
│ └── QRScanner/
│ └── QRScannerDialog.vue # Shared UI component
└── views/
├── ContactQRScanView.vue # Dedicated scanning view
└── ContactQRScanShowView.vue # Combined QR display and scanning view
Core Components
-
Factory Pattern
QRScannerFactory
- Creates appropriate scanner instance based on platform- Common interface
QRScannerService
implemented by all scanners - Platform detection via Capacitor and build flags
-
Platform-Specific Implementations
CapacitorQRScanner
- Native mobile implementation using MLKitWebInlineQRScanner
- Web browser implementation using MediaDevices APIQRScannerDialog.vue
- Shared UI component
-
View Components
ContactQRScanView
- Dedicated view for scanning QR codesContactQRScanShowView
- Combined view for displaying and scanning QR codes
Implementation Details
Core Interfaces
interface QRScannerService {
checkPermissions(): Promise<boolean>;
requestPermissions(): Promise<boolean>;
isSupported(): Promise<boolean>;
startScan(options?: QRScannerOptions): Promise<void>;
stopScan(): Promise<void>;
addListener(listener: ScanListener): void;
onStream(callback: (stream: MediaStream | null) => void): void;
cleanup(): Promise<void>;
}
interface ScanListener {
onScan: (result: string) => void;
onError?: (error: Error) => void;
}
interface QRScannerOptions {
camera?: "front" | "back";
showPreview?: boolean;
playSound?: boolean;
}
Platform-Specific Implementations
Mobile (Capacitor)
- Uses
@capacitor-mlkit/barcode-scanning
- Native camera access through platform APIs
- Optimized for mobile performance
- Supports both iOS and Android
- Real-time QR code detection
- Back camera preferred for scanning
Configuration:
// capacitor.config.ts
const config: CapacitorConfig = {
plugins: {
MLKitBarcodeScanner: {
formats: ['QR_CODE'],
detectorSize: 1.0,
lensFacing: 'back',
googleBarcodeScannerModuleInstallState: true
}
}
};
Web
- Uses browser's MediaDevices API
- Vue.js components for UI
- EventEmitter for stream management
- Browser-based camera access
- Inline camera preview
- Responsive design
- Cross-browser compatibility
View Components
ContactQRScanView
- Dedicated view for scanning QR codes
- Full-screen camera interface
- Simple UI focused on scanning
- Used primarily on native platforms
- Streamlined scanning experience
ContactQRScanShowView
- Combined view for QR code display and scanning
- Shows user's own QR code
- Handles user registration status
- Provides options to copy contact information
- Platform-specific scanning implementation:
- Native: Button to navigate to ContactQRScanView
- Web: Built-in scanning functionality
QR Code Workflow
-
Initiation
- User selects "Scan QR Code" option
- Platform-specific scanner is initialized
- Camera permissions are verified
- Appropriate scanner component is loaded
-
Platform-Specific Implementation
- Web: Uses
qrcode-stream
for real-time scanning - Native: Uses
@capacitor-mlkit/barcode-scanning
- Web: Uses
-
Scanning Process
- Camera stream initialization
- Real-time frame analysis
- QR code detection and decoding
- Validation of QR code format
- Processing of contact information
-
Contact Processing
- Decryption of contact data
- Validation of user information
- Verification of timestamp
- Check for duplicate contacts
- Processing of shared data
Build Configuration
Common Vite Configuration
// vite.config.common.mts
export async function createBuildConfig(mode: string) {
const isCapacitor = mode === "capacitor";
return defineConfig({
define: {
'process.env.VITE_PLATFORM': JSON.stringify(mode),
'process.env.VITE_PWA_ENABLED': JSON.stringify(!isNative),
__IS_MOBILE__: JSON.stringify(isCapacitor),
__USE_QR_READER__: JSON.stringify(!isCapacitor)
},
optimizeDeps: {
include: [
'@capacitor-mlkit/barcode-scanning',
'vue-qrcode-reader'
]
}
});
}
Platform-Specific Builds
{
"scripts": {
"build:web": "vite build --config vite.config.web.mts",
"build:capacitor": "vite build --config vite.config.capacitor.mts",
"build:all": "npm run build:web && npm run build:capacitor"
}
}
Error Handling
Common Error Scenarios
- No camera found
- Permission denied
- Camera in use by another application
- HTTPS required
- Browser compatibility issues
- Invalid QR code format
- Expired QR codes
- Duplicate contact attempts
- Network connectivity issues
Error Response
- User-friendly error messages
- Troubleshooting tips
- Clear instructions for resolution
- Platform-specific guidance
Security Considerations
QR Code Security
- Encryption of contact data
- Timestamp validation
- Version checking
- User verification
- Rate limiting for scans
Data Protection
- Secure transmission of contact data
- Validation of QR code authenticity
- Prevention of duplicate scans
- Protection against malicious codes
- Secure storage of contact information
Best Practices
Camera Access
- Always check for camera availability
- Request permissions explicitly
- Handle all error conditions
- Provide clear user feedback
- Implement proper cleanup
Performance
- Optimize camera resolution
- Implement proper resource cleanup
- Handle camera switching efficiently
- Manage memory usage
- Battery usage optimization
User Experience
- Clear visual feedback
- Camera preview
- Scanning status indicators
- Error messages
- Success confirmations
- Intuitive camera controls
- Smooth camera switching
- Responsive UI feedback
Testing
Test Scenarios
- Permission handling
- Camera switching
- Error conditions
- Platform compatibility
- Performance metrics
- QR code detection
- Contact processing
- Security validation
Test Environment
- Multiple browsers
- iOS and Android devices
- Various network conditions
- Different camera configurations
Dependencies
Key Packages
@capacitor-mlkit/barcode-scanning
qrcode-stream
vue-qrcode-reader
- Platform-specific camera APIs
Maintenance
Regular Updates
- Keep dependencies updated
- Monitor platform changes
- Update documentation
- Review security patches
Performance Monitoring
- Track memory usage
- Monitor camera performance
- Check error rates
- Analyze user feedback