fix: 14 audit fixes — concurrency, memory, performance, accessibility
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>
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import LRUCache
|
||||
|
||||
actor RemoteImageService {
|
||||
|
||||
@@ -32,7 +33,7 @@ actor RemoteImageService {
|
||||
// MARK: - Properties
|
||||
|
||||
private let urlSession: URLSession
|
||||
private var imageCache: [URL: UIImage] = [:]
|
||||
private let imageCache = LRUCache<URL, UIImage>(countLimit: 50)
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
@@ -56,7 +57,7 @@ actor RemoteImageService {
|
||||
/// Fetch a single image from URL
|
||||
func fetchImage(from url: URL) async throws -> UIImage {
|
||||
// Check cache first
|
||||
if let cached = imageCache[url] {
|
||||
if let cached = imageCache.value(forKey: url) {
|
||||
return cached
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ actor RemoteImageService {
|
||||
let scaledImage = scaleImage(image, maxWidth: 400)
|
||||
|
||||
// Cache it
|
||||
imageCache[url] = scaledImage
|
||||
imageCache.setValue(scaledImage, forKey: url)
|
||||
|
||||
return scaledImage
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user