Remove BlueCharmProvisioner, KBeaconProvisioner, and FallbackProvisioner. Simplify BeaconType enum to DX-Smart only. Simplify BLE detection to only show CP-28 beacons. Remove multi-type provisioner factory from ScanView. -989 lines of dead code removed. Other beacon types will be re-added when we start using different hardware. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.9 KiB
4.9 KiB
Payfrit Beacon iOS
Native Swift iOS app for provisioning iBeacon hardware at restaurant tables. Repo: payfrit-beacon-ios on Forgejo.
Purpose
Utility app for restaurant setup staff to:
- Scan for nearby BLE iBeacons (iBeacon + BLE + QR code)
- Check UUID against known bulk manufacturer defaults (ban list)
- Assign table names to beacons (smart-incremented)
- Provision beacon hardware via BLE GATT (DX-Smart, BlueCharm, KBeacon)
- Save beacon + auto-create service point records via API
Environment
- Server: dev.payfrit.com (DEBUG) / biz.payfrit.com (RELEASE)
- API Base:
https://dev.payfrit.com/api(dev) /https://biz.payfrit.com/api(prod) - Config:
APIConfig.swift— uses#if DEBUGcompiler flag - OTP: Dev server uses magic OTP
123456(no Twilio)
Database (via API — no direct SQL)
| Table | PK | Key Columns |
|---|---|---|
| Beacons | ID |
UUID, Name, BusinessID, IsActive |
| ServicePoints | ID |
BusinessID, Name, TypeID, Code, SortOrder, IsActive, BeaconID |
| Businesses | ID |
Name, ParentBusinessID |
Note: POST /api/beacons/save.php auto-creates a ServicePoint when saving a beacon.
API Endpoints Used
All endpoints are .php. Auth = X-User-Token header.
| Method | Endpoint | Auth | Purpose |
|---|---|---|---|
| POST | /auth/loginOTP.php | No | Send OTP to phone |
| POST | /auth/verifyLoginOTP.php | No | Verify OTP, get token |
| POST | /businesses/list.php | Yes | List user's businesses |
| POST | /servicepoints/list.php | Yes | List service points for business |
| POST | /servicepoints/save.php | Yes | Create/update service point |
| POST | /servicepoints/delete.php | Yes | Delete service point |
| POST | /beacon-sharding/allocate_business_namespace.php | Yes | Allocate UUID+Major shard |
| POST | /beacon-sharding/get_beacon_config.php | Yes | Get complete beacon config |
| POST | /beacon-sharding/allocate_servicepoint_minor.php | Yes | Auto-assign minor value |
| POST | /beacon-sharding/resolve_business.php | Yes | Resolve business by UUID+Major |
| POST | /beacons/list.php | Yes | List beacons for a business |
| POST | /beacons/lookupByMac.php | Yes | Lookup beacon by MAC address |
| POST | /beacons/wipe.php | Yes | Decommission a beacon |
| GET | /users/profile.php | Yes | Get user profile |
Build & Deploy
Build in Xcode targeting iOS 17+. No local testing — deploy to device for BLE testing.
Project Structure
PayfritBeacon/
├── App/
│ ├── AppPrefs.swift UserDefaults keys
│ ├── AppState.swift ObservableObject — auth state, nav, business selection
│ └── PayfritBeaconApp.swift App entry point
├── Models/
│ ├── BeaconConfig.swift Provisioning config (UUID, major, minor, txPower, etc.)
│ ├── BeaconType.swift Enum: DXSmart (CP-28 only)
│ ├── Business.swift Business model
│ └── ServicePoint.swift Service point model
├── Provisioners/
│ ├── ProvisionerProtocol.swift Protocol + CP-28 GATT constants
│ ├── DXSmartProvisioner.swift DX-Smart CP-28 GATT provisioner (24-step write sequence)
│ └── ProvisionError.swift Shared error types
├── Services/
│ ├── APIClient.swift Actor-based REST client, all API calls
│ ├── APIConfig.swift Base URLs, timeouts, dev/prod toggle
│ ├── BLEManager.swift CoreBluetooth scanning + beacon type detection
│ └── SecureStorage.swift Keychain-based token storage
├── Utils/
│ ├── BeaconBanList.swift Known bad UUID prefixes (factory defaults)
│ ├── BeaconShardPool.swift 64 Payfrit shard UUIDs
│ └── UUIDFormatting.swift UUID string formatting extensions
└── Views/
├── BusinessListView.swift Business selection screen
├── DevBanner.swift Orange "DEV" banner overlay
├── LoginView.swift OTP login screen
├── QRScannerView.swift Camera-based QR code scanner for beacon pairing
├── RootView.swift Root navigation
└── ScanView.swift Main scan + provision UI
Key Architecture Notes
- CP-28 only: Only DX-Smart CP-28 beacons are supported. Other beacon types (KBeacon, BlueCharm) were removed — will be re-added when needed.
- Actor-based API:
APIClientis a Swift actor (thread-safe by design). - Secure storage: Auth tokens stored in Keychain via
SecureStorage, not UserDefaults. - BLE scanning:
BLEManagerhandles CoreBluetooth device discovery and beacon type identification. - DX-Smart protocol: 24-step write sequence including frames 3-6 disable (full Android parity).
- QR scanner: Camera-based QR code scanning for beacon pairing workflows.