KBeaconProvisioner had no onStatusUpdate callback, so the UI showed a static
"Connecting..." message during the entire auth cycle (5 passwords × 5s timeout
× 3 retries = 75s of dead silence). Now reports each phase: connecting,
discovering services, authenticating (with password attempt count), writing,
saving.
Also fixed ScanView disconnect handler to cover .writing and .verifying states —
previously only handled .connecting/.connected, so a mid-write disconnect left
the UI permanently stuck.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DXSmartProvisioner now reports each phase (connecting, discovering
services, authenticating, retrying) via onStatusUpdate callback
- ScanView shows live diagnostic log during connecting/writing states,
not just on failure — so you can see exactly where it stalls
- Unexpected BLE disconnects now properly update provisioningState to
.failed instead of silently logging
- Added cancel button to connecting progress view
- "Connected" screen title changed to "Connected — Beacon is Flashing"
for clearer status indication
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BIG FIX: Provisioners were calling centralManager.connect() but
BLEManager is the CBCentralManagerDelegate — provisioners never
received didConnect/didFailToConnect callbacks, so connections
ALWAYS timed out after 5s regardless. This is why provisioning
kept failing. Fixed by:
1. Adding didConnect/didFailToConnect/didDisconnect to BLEManager
2. Provisioners register connection callbacks via bleManager
3. Increased connection timeout from 5s to 10s
DIAGNOSTICS: Added ProvisionLog system so failures show a timestamped
step-by-step log of what happened (with Share button). Every phase
is logged: init, API calls, connect attempts, service discovery,
auth, write commands, and errors.
Sort the beacon list so strongest signal (closest beacon) appears at the
top. Sorting happens both in BLEManager as beacons are discovered and in
the ScanView list rendering.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When tapping Back from ScanView, BusinessListView remounts and .task fires
loadBusinesses() which sees AppPrefs.lastBusinessId still set — immediately
re-navigating into the same business. Fix: clear lastBusinessId on back,
and add skipAutoNav flag to also prevent single-business auto-select from
firing when user explicitly navigated back.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The app crashed immediately when tapping QR scan because the Info.plist
was missing the required NSCameraUsageDescription key. iOS kills the app
with EXC_BAD_INSTRUCTION when camera access is requested without it.
Also fixes:
- Flash toggle could SIGABRT if lockForConfiguration failed (try? + unconditional unlock)
- Camera setup now logs errors instead of silently failing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The ShapeStyle where Self == Color extension duplicated Color statics,
causing 'ambiguous use' errors in foregroundStyle/stroke/tint/background
contexts. Removed the extension entirely and use explicit Color.xxx prefix
at all call sites instead.
- App icon now uses white bg + PAYFRIT text + bluetooth beacon icon (matches Android)
- AccentColor set to Payfrit Green (#22B24B)
- Added BrandColors.swift with full Android color palette parity
- All views updated: payfritGreen replaces .blue, proper status colors throughout
- Signal strength, beacon type badges, QR scanner corners all use brand colors
- DevBanner uses warningOrange matching Android's #FF9800
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use explicit toolbar(content:) call instead of trailing closure to
disambiguate the SwiftUI toolbar modifier overload.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- QRScannerView: AVFoundation camera + barcode/QR detection with
flashlight toggle, viewfinder overlay, MAC/UUID pattern recognition
- New API endpoints: deleteServicePoint, updateServicePoint,
listBeacons, decommissionBeacon, lookupByMac, getBeaconStatus, getProfile
- Wire QR scanner into ScanView with BLE Scan + QR Scan side-by-side
- MAC address lookup on scan to check if beacon already registered
- Updated Xcode project file with new source
- Flatten project structure: remove Models/, Services/, ViewModels/, Views/ subdirs
- Replace APIService actor with simpler Api class, IS_DEV flag controls dev vs prod URL
- Rewrite BeaconScanner to use CoreLocation (CLBeaconRegion ranging) instead of
CoreBluetooth — iOS blocks iBeacon data from CBCentralManager
- Add SVG logo on login page with proper scaling (was showing green square)
- Make login page scrollable, add "enter 6-digit code" OTP instruction
- Fix text input visibility (white on white) with .foregroundColor(.primary)
- Add diagonal orange DEV ribbon banner (lower-left corner), gated on Api.IS_DEV
- Update app icon: logo 10% larger, wifi icon closer
- Add en.lproj/InfoPlist.strings for display name localization
- Fix scan flash: keep isScanning=true until enrichment completes
- Add Podfile with SVGKit, Kingfisher, CocoaLumberjack dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>