Second audit round addressing data races, task stacking, unbounded caches, and VoiceOver gaps across 7 files. Concurrency: - Move NSItemProvider @State access into MainActor block (3 drop handlers) - Cancel stale ScheduleViewModel tasks on rapid filter changes Memory: - Replace unbounded image dict with LRUCache(countLimit: 50) - Replace demo-mode asyncAfter with cancellable Task Performance: - Wrap debug NBA print() in #if DEBUG - Cache visitsById via @State + onChange instead of per-render computed - Pre-compute sportProgressFractions in ProgressViewModel - Replace allGames computed property with hasGames bool check - Cache sortedTrips via @State + onChange in SavedTripsListView Accessibility: - Add combined VoiceOver label to progress ring - Combine away/home team text into single readable phrase - Hide decorative StadiumDetailSheet icon from VoiceOver - Add explicit accessibilityLabel to SportFilterChip - Add combined accessibilityLabel to GameRowView Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.2 KiB
5.2 KiB