100% fresh codebase — no legacy code carried over. Built against the Android beacon app as the behavioral spec. Architecture: - App: SwiftUI @main, AppState-driven navigation, Keychain storage - Views: LoginView (OTP + biometric), BusinessListView, ScanView (provisioning hub) - Models: Business, ServicePoint, BeaconConfig, BeaconType, DiscoveredBeacon - Services: APIClient (actor, async/await), BLEManager (CoreBluetooth scanner) - Provisioners: KBeacon, DXSmart (2-step auth + flashing), BlueCharm - Utils: UUIDFormatting, BeaconBanList, BeaconShardPool (64 shards) Matches Android feature parity: - 4-screen flow: Login → Business Select → Scan/Provision - 3 beacon types with correct GATT protocols and timeouts - Namespace allocation via beacon-sharding API - Smart service point naming (Table N auto-increment) - DXSmart special flow (connect → flash → user confirms → write) - Biometric auth, dev/prod build configs, DEV banner overlay Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
33 lines
843 B
Swift
33 lines
843 B
Swift
import Foundation
|
|
import CoreBluetooth
|
|
|
|
/// Supported beacon hardware types
|
|
enum BeaconType: String, CaseIterable {
|
|
case kbeacon = "KBeacon"
|
|
case dxsmart = "DX-Smart"
|
|
case bluecharm = "BlueCharm"
|
|
case unknown = "Unknown"
|
|
}
|
|
|
|
/// A BLE beacon discovered during scanning
|
|
struct DiscoveredBeacon: Identifiable {
|
|
let id: UUID // CBPeripheral identifier
|
|
let peripheral: CBPeripheral
|
|
let name: String
|
|
let type: BeaconType
|
|
var rssi: Int
|
|
var lastSeen: Date
|
|
|
|
var displayName: String {
|
|
name.isEmpty ? "\(id.uuidString.prefix(8))…" : name
|
|
}
|
|
|
|
var signalDescription: String {
|
|
switch rssi {
|
|
case -50...0: return "Excellent"
|
|
case -65 ... -51: return "Good"
|
|
case -80 ... -66: return "Fair"
|
|
default: return "Weak"
|
|
}
|
|
}
|
|
}
|