Fix 25 audit issues: memory leaks, concurrency, performance, accessibility

Address findings from comprehensive audit across 5 workstreams:

- Memory: Token-based DataController listeners (prevent closure leaks),
  static DateFormatters, ImageCache observer cleanup, MotionManager
  reference counting, FoundationModels dedup guard
- Concurrency: Replace Task.detached with Task in FeelsApp (preserve
  MainActor isolation), wrap WatchConnectivity handler in MainActor
- Performance: Cache sortedGroupedData in DayViewViewModel, cache demo
  data in MonthView/YearView, remove broken ReduceMotionModifier
- Accessibility: VoiceOver support for LockScreen, DemoHeatmapCell
  labels, MonthCard button labels, InsightsView header traits,
  Smart Invert protection on neon headers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-19 09:11:48 -06:00
parent b58dfd5093
commit c22d246865
18 changed files with 175 additions and 73 deletions

View File

@@ -15,13 +15,15 @@ final class ImageCache {
private let cache = NSCache<NSString, UIImage>()
private let queue = DispatchQueue(label: "com.tt.feels.imagecache", qos: .userInitiated)
private var memoryWarningToken: NSObjectProtocol?
private init() {
// Configure cache limits
cache.countLimit = 100 // Max 100 images
cache.totalCostLimit = 50 * 1024 * 1024 // 50 MB max
// Clear cache on memory warning
NotificationCenter.default.addObserver(
memoryWarningToken = NotificationCenter.default.addObserver(
forName: UIApplication.didReceiveMemoryWarningNotification,
object: nil,
queue: .main
@@ -30,6 +32,12 @@ final class ImageCache {
}
}
deinit {
if let token = memoryWarningToken {
NotificationCenter.default.removeObserver(token)
}
}
// MARK: - Public API
/// Get image from cache