QR scanners are a deceptively rich mobile system design problem. Camera capture in real time, edge case handling (low light, glare, partial occlusion), security screening for malicious URLs, and the lightweight UX patterns expected from “open camera, point, done.”
Functional requirements
- Detect a QR code in the camera feed in real time
- Decode the contents
- Take an appropriate action: open URL, add contact, copy text, etc.
- Security check: warn on suspicious URLs
- Multi-code support: detect and let user pick if multiple visible
Architecture
Three steps: capture, detect, act.
Camera capture
iOS: AVCaptureSession at 30fps. Each frame is a CVPixelBuffer.
Android: CameraX library, simpler API.
Use the back camera, autofocus on the center, set white balance auto. Resolution: 720p or 1080p — higher does not improve detection meaningfully but costs battery.
Detection
Native APIs handle this:
- iOS: AVMetadataMachineReadableCodeObject — built into AVFoundation
- Android: ML Kit Barcode Scanning
Both run on every camera frame. Detection latency <100ms. Returns the decoded payload + bounding box in image coordinates.
Decoding edge cases
- Low light: flash toggle
- Glare: ask user to adjust angle
- Partially occluded: QR has error correction; works with up to 30% damage
- Multiple codes in frame: highlight all, let user tap to pick
- Wrong code type detected (barcode vs QR): support multiple types
Action handling
QR payloads can be:
- URL → open in browser (or app deep link if matches a known scheme)
- vCard → add contact
- Wi-Fi credentials → join network
- SMS / mailto → compose message
- Plain text → copy to clipboard
- App-specific (e.g., shared content) → open in your app
Security: malicious URLs
QR codes are a common phishing vector. Mitigations:
- Show the URL prominently before opening
- Warn on URL shorteners (bit.ly, t.co)
- Check against known-bad-URL lists (Safe Browsing API)
- Warn on punycode / IDN homograph URLs (e.g., аpple.com using Cyrillic а)
UX patterns
- Open camera with QR scanner mode highlighted
- Reticle overlay to suggest aiming
- Haptic feedback when code detected
- Modal with decoded content + action button
Battery
- Detection only when camera is open
- Stop detection after first successful scan; user takes action
- Lower frame rate (15fps) is sufficient
iOS Live Text and Camera Continuity
iOS automatically detects QR codes in the system Camera app since iOS 15. Apps can leverage VisionKit’s DataScannerViewController for the same UX in their own apps.
Frequently Asked Questions
Why do some QR scanners detect codes faster than others?
Differences in frame rate, ROI cropping, and image preprocessing. Native APIs are usually faster than custom solutions.
How does Apple Pay use QR codes?
For merchant present codes — user scans, app produces a payment from the encoded merchant info. Different from displaying a code for the merchant to scan.
Should I implement QR codes manually for special cases?
No. Native APIs are mature. Custom decoders are slower and brittle to edge cases.