payfrit-beacon-ios/PayfritBeacon/Services/ProvisionLog.swift
Schwifty c243235237 fix: connection callback bug + add provisioning diagnostics
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.
2026-03-22 23:12:06 +00:00

56 lines
1.7 KiB
Swift

import Foundation
/// Timestamped diagnostic log for beacon provisioning.
/// Captures every step so we can diagnose failures.
@MainActor
final class ProvisionLog: ObservableObject {
struct Entry: Identifiable {
let id = UUID()
let timestamp: Date
let phase: String // "connect", "discover", "auth", "write", "verify"
let message: String
let isError: Bool
var formatted: String {
let t = Self.formatter.string(from: timestamp)
let prefix = isError ? "" : ""
return "\(t) [\(phase)] \(prefix) \(message)"
}
private static let formatter: DateFormatter = {
let f = DateFormatter()
f.dateFormat = "HH:mm:ss.SSS"
return f
}()
}
@Published private(set) var entries: [Entry] = []
private var startTime: Date?
/// Clear log for a new provisioning attempt
func reset() {
entries = []
startTime = Date()
}
/// Add a log entry
func log(_ phase: String, _ message: String, isError: Bool = false) {
let entry = Entry(timestamp: Date(), phase: phase, message: message, isError: isError)
entries.append(entry)
}
/// Elapsed time since reset
var elapsed: String {
guard let start = startTime else { return "0.0s" }
let seconds = Date().timeIntervalSince(start)
return String(format: "%.1fs", seconds)
}
/// Full log as shareable text
var fullText: String {
let header = "Payfrit Beacon Diagnostic Log"
let time = "Session: \(elapsed)"
let lines = entries.map { $0.formatted }
return ([header, time, "---"] + lines).joined(separator: "\n")
}
}