Building an unofficial Dumpert client for Apple TV with Swift 6 and SwiftUI
Dumpert is a Dutch video site I've watched for years, but there's never been an Apple TV app, so I built one. DumpertTV is an unofficial, open-source tvOS client. Here's how it's put together and a few things that were more interesting than I expected. Disclaimer up front: this project is not affiliated with Dumpert or DPG Media B.V. It's an independent app that uses the public Dumpert API. The stack Swift 6 with strict concurrency ( complete mode) across every target SwiftUI for all UI, tvOS 18+ XcodeGen so the .xcodeproj is generated from a project.yml and never committed CloudKit , GroupActivities (SharePlay), Vision , AVKit , Swift Testing One actor for the network, one source of truth for the UI The whole networking layer is an actor . That makes per-request state like ETags and retry bookkeeping thread-safe without a single lock: actor DumpertAPIClient { private var etags : [ URL : String ] = [:] func fetch < T : Decodable > ( _ endpoint : APIEndpoint ) async throws -> T { // Exponential backoff on 5xx + network errors; honours 304 Not Modified. try await fetchWithRetry ( endpoint , attempt : 0 ) } } The UI reads from a single @Observable @MainActor repository injected through the SwiftUI environment — no Combine, no view models competing over the same state: @Observable @MainActor final class VideoRepository { private(set) var hotshiz : [ MediaItem ] = [] let apiClient : APIClientProtocol // protocol-backed for testing } ContentView () . environment ( videoRepository ) Views just read repository.hotshiz ; updates flow automatically. With Swift 6's strict concurrency on, the compiler kept me honest about every actor hop. Things that were trickier than expected tvOS focus + a top tab bar. Getting a Netflix-style hero carousel to behave with the focus engine took real care. It also made automating screenshots interesting — scripted remote input doesn't reliably drive the simulator, so I added #if DEBUG launch-argument hooks to jump straight to any tab/category f