Skip to content

refactor: Clean up logging, error handling, and AVFoundation helpers#11

Open
oscnord wants to merge 7 commits intomainfrom
improvements/codebase-cleanup
Open

refactor: Clean up logging, error handling, and AVFoundation helpers#11
oscnord wants to merge 7 commits intomainfrom
improvements/codebase-cleanup

Conversation

@oscnord
Copy link
Copy Markdown
Owner

@oscnord oscnord commented May 1, 2026

Summary

Branch-scoped cleanup pass tackling 8 of the 10 items from the codebase audit. Focused on the high-value, low-risk items; the two architecturally invasive items (god-object ViewModel split, long-view decomposition) are flagged for dedicated follow-up PRs.

Commit Item
459145a P4 centralized os.Logger (21 prints removed); GCD → Swift Concurrency (9 sites)
459145a P6 force-unwrap removal across analyzers, extractors, server, CLI; safer appSupport fallback; logged the previously-silent JSON load errors
459231e P7 new AVAssetLoader consolidating ~17 duplicated AVFoundation lookup patterns
1814a0d P9 modifier strings wrapped in String(localized:)
ca58a6f P3 generic LRUCache<Key, Value> replacing the hand-rolled GOP cache plumbing on the ViewModel
33d053b P1 stale AnalysisEngine migration TODO removed; docstring now describes the actual build wiring
64f98c4 P5 30 new tests across CSVExporter, JSONExporter, formatting utils, and LRUCache

Deferred for follow-up PRs

  • P10 Inline .font(.system(size:weight:design:)) calls — best handled together with P8.
  • P2 Split MediaInspectorViewModel into AnalysisCoordinator + SettingsStore + TabContext — multi-day refactor across 11 files; should be phased with UI smoke-tests at each phase.
  • P8 Break up VideoPlayerView (1,220), TimelineView (1,061), GOPHeatmapView (969) — each warrants its own PR with screenshot/UI verification.

Test plan

  • xcodebuild -project FramePeek/FramePeek.xcodeproj -scheme FramePeek build (passes)
  • xcodebuild -project FramePeek/FramePeek.xcodeproj -scheme FramePeekCLI build (passes)
  • xcodebuild -project FramePeek/FramePeek.xcodeproj -scheme FramePeek test -only-testing:FramePeekCoreTests (30/30 pass)
  • Smoke test app: drop a file, run each tab (Bitrate, GOP, Color, Sync, Waveforms, Inspector, Container)
  • Smoke test CLI: framepeek-cli analyze <file> --json against MP4, MPEG-TS, fragmented MP4
  • Verify embedded server still starts and /health responds

oscnord added 7 commits May 1, 2026 11:26
Replace 21 print() call sites with a typed os.Logger wrapper (Log.analysis,
Log.media, Log.parsing, Log.server, Log.ui, Log.cli) so log output flows
through the system unified logging facility instead of stdout.

Drop 9 DispatchQueue.main.async usages in favor of Task { @mainactor in } and
Task.detached, aligning with AGENTS.md's Swift Concurrency mandate.

Eliminate force unwraps in production code paths: replace .first! / .last!
sequences with guard-let bindings on first/last; resolve TimelineView's
double-evaluated nil-check pattern; add Application Support fallbacks in
JobQueue/ServerManager; convert HTTPField.Name(...)! and .data(using:)!
to safe forms; surface previously-silent JSON load errors in JobHistory and
ServerManager.
Add FramePeek/Utils/Media/AVAssetLoader.swift with typed helpers
(durationSeconds, firstTrack, tracks, nominalFrameRate, estimatedDataRate,
formatDescriptions, firstFormatDescription) and route the highest-frequency
asset.load(.X) / loadTracks(withMediaType:) call sites through it.

Replaces ~17 instances of (try? await ...) ?? default scattered across
analyzers, extractors, and info loaders, removing one of the more painful
sources of duplication and giving us a single seam where AVFoundation lookups
can later be mocked or instrumented.
Per AGENTS.md, .help and .accessibilityLabel modifiers need explicit
String(localized:) since they don't get SwiftUI's auto-localization that
Text(...) gets. The five modifier-strings that were missing this wrap are
now covered.

Sweeping the rest of the codebase requires first adding a Strings catalog
(.xcstrings); that infrastructure work is out of scope for this pass.
Add LRUCache<Key, Value> to CacheManager.swift, then collapse the three
properties (gopFrameDetailsCache dictionary, gopCacheAccessOrder array,
gopCacheMaxSize constant) plus the cache/get/clear functions on
MediaInspectorViewModel down to a single LRUCache<UUID, [FrameInfo]>.

Eliminates the duplicated bookkeeping between dictionary and access-order
array, and gives waveform/sync caches the same primitive to use later if
they want in-memory layers.
The analyzer files already compile into FramePeekCore (via the
'membershipExceptions' overrides on project.pbxproj's synced FramePeek
folder), and the CLI consumes them through the framework. Update the
docstring to describe how the build is wired today instead of
instructing the next reader to do the migration that has already
shipped.
Replace the placeholder FramePeekCoreTests target with four real suites
covering: CSVExporter (header rows, empty data, file-info preamble,
roundtrip), JSONExporter (round-trip decode, pretty-print sorted keys,
multi-file wrapper), formatting utilities (formatDuration, timecode,
channel layout, aspect ratio matching with PAR, resolution category, gcd,
isVerticalResolution), and the new LRUCache (insertion, eviction,
get-promotes-MRU, re-insert, clear, keys).

30 tests, all passing. Establishes the test foundation that future
analyzer/engine tests can build on.
@oscnord oscnord changed the title Codebase cleanup: logging, error handling, AVAsset helpers, LRU, and tests refactor: Clean up logging, error handling, and AVFoundation helpers May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant