tvOS: Developing for Apple TV with Focus Engine

Author: IT Sectr Published: 2026-02-07 Reading time: 11 min

tvOS — Apple's operating system for Apple TV, first released in 2015 alongside the 4th generation Apple TV. App development for tvOS is done in Swift using SwiftUI and TVMLKit. The key difference from iOS is focus control via the Siri Remote instead of touch. According to Apple, tvOS is installed on over 100 million active devices worldwide.

Key Takeaways

  • tvOS — Apple's OS for TV set-top boxes on the XNU kernel with Focus Engine instead of touch
  • Focus Engine — focus management system between elements via Siri Remote
  • SwiftUI and TVMLKit — two development approaches: native and JavaScript templates
  • Top Shelf — dynamic content on the Apple TV home screen
  • App size strictly limited to 4 GB, recommended no more than 500 MB

What is tvOS?

tvOS — Apple's operating system for Apple TV set-top boxes, based on the same Darwin XNU kernel as iOS. First released on October 30, 2015 with the 4th generation Apple TV. tvOS replaced the outdated Apple TV Software (based on iOS, without App Store and SDK). The system is optimized for TV operation with resolutions up to 4K HDR (Dolby Vision) and Dolby Atmos sound.

According to Apple (WWDC 2025), tvOS is installed on Apple TV HD (2015), Apple TV 4K (2017, 2021, 2022) and is built into some Smart TV models via AirPlay. Apple TV uses A8 (HD), A10X Fusion (1st gen 4K), A12 Bionic (2nd gen 4K) and A15 Bionic (3rd gen 4K) chips. All models support tvOS 17. tvOS has no camera, microphone (except remote), touch screen, or GPS.

The key feature of tvOS is the Focus Engine, which replaces touch control with focus navigation. The user moves the selection between UI elements using the Siri Remote. Developers create apps in Swift/SwiftUI (native) or JavaScript/TVML (media apps like Netflix, Hulu).

tvOS Version History

tvOS 9 (2015) — first version with SDK and App Store. tvOS 10 (2016) — Single Sign-On (SSO) for cable subscriptions. tvOS 11 (2017) — Amazon Prime Video support and automatic mode. tvOS 12 (2018) — Dolby Atmos. tvOS 13 (2019) — multi-user mode. tvOS 17 (2023) — FaceTime, VPN, audio profiles via HDMI.

tvOS VersionYearKey Innovation
tvOS 92015App Store, SDK, Siri Remote
tvOS 102016Single Sign-On (SSO), Live Tune-In
tvOS 112017Amazon Prime, automatic mode
tvOS 122018Dolby Atmos, password with iPhone
tvOS 132019Multi-user, Control Center on TV
tvOS 172023FaceTime, VPN, Find My Siri Remote

tvOS Architecture and Differences from iOS

The tvOS architecture is based on the same stack as iOS: XNU kernel, Core Services system services, Media layer, and the Cocoa Touch user layer. However, there are significant differences related to the specifics of the TV platform.

Hardware Limitations

The 3rd generation Apple TV 4K uses A15 Bionic with 6 CPU cores (2 performance, 4 efficiency) and a 5-core GPU. RAM — 4 GB (internal SSD storage from 64 GB). The system does not have persistent local storage in the classic sense: all app data may be deleted by tvOS when space is low (purgeable). Developers must use iCloud Key-Value Storage or CloudKit for state preservation.

TVMLKit and TVJS

TVMLKit — a framework unique to tvOS that allows creating interfaces in JavaScript and TVML (Apple-specific XML-like language). TVMLKit loads JSON/XML from the server and renders native UI components. This is the primary technology for streaming services: Netflix, Hulu, Amazon Prime Video use TVMLKit. TVJS — a JavaScript environment running in an isolated context.

Lack of Persistent Storage

tvOS automatically manages disk space: when space is low, the system may delete cache, downloaded resources, and even the app itself (while keeping the icon). Upon reopening, the app must restore its state. iCloud NSUbiquitousKeyValueStore is the only guaranteed persistent storage for settings (up to 1 MB per app).

swift
import Foundation

// // State preservation and restoration in tvOS
final class StateManager {

    private let store = NSUbiquitousKeyValueStore.default
    private let coder = JSONEncoder()
    private let decoder = JSONDecoder()

    // Saving viewing progress
    func saveProgress<T: Codable>(_ value: T, for key: String) {
        if let data = try? coder.encode(value) {
            store.set(data, for: key)
            store.synchronize()
        }
    }

    // Restoring state after cache deletion
    func restoreProgress<T: Codable>(_ type: T.Type, for key: String) -> T? {
        guard let data = store.data(for: key) else { return nil }
        return try? decoder.decode(type, from: data)
    }

    // Handling change notification on another device
    init() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(ubiquitousKeyValueStoreDidChange),
            name: NSUbiquitousKeyValueStore.didChangeExternallyNotification,
            object: store
        )
    }

    @objc
    private func ubiquitousKeyValueStoreDidChange(_ notification: Notification) {
        print("Data changed on another device")
    }
}

The StateManager uses NSUbiquitousKeyValueStore to save app state on tvOS. Since local storage can be cleared by the system, only iCloud guarantees data persistence. store.synchronize() immediately sends data to the server, while didChangeExternallyNotification notifies the app about changes from the user's other devices.

Focus Engine: Navigation and Focus

Focus Engine — the key mechanism of tvOS that replaces touch events with focus navigation. The user moves the selection between UI elements using the Siri Remote (touch surface or buttons). The system automatically calculates the next focus element based on distance and direction of movement.

UIFocusEnvironment and Focus Hierarchy

Each UI element capable of receiving focus implements the UIFocusEnvironment protocol. UIKit automatically determines the navigation order based on element geometry. The developer can override the preferred focus via preferredFocusEnvironments, specify an array of child focusEnvironment, and control movement through UIFocusHeading (up, down, left, right). UIFocusGuide allows setting custom routes for non-trivial layouts.

UIFocusEffect and Parallax

tvOS automatically adds UIFocusEffect to the focused element: shadow, highlight, and parallax effect (offset when tilting the remote). The developer can disable the effect via focusedValue or customize it through UIFocusEffect.transform. In SwiftUI, parallax is added with the .hoverEffect(.highlight) modifier.

swift
import SwiftUI

// // tvOS component with custom focus
struct MovieCardView: View {
    let movie: Movie
    @State private var isFocused = false
    @Environment(\.isFocused) var envFocused

    var body: some View {
        VStack(spacing: 8) {
            AsyncImage(url: movie.posterURL) { phase in
                if let image = phase.image {
                    image
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 320, height: 180)
                        .cornerRadius(8)
                        .overlay(
                            RoundedRectangle(cornerRadius: 8)
                                .stroke(isFocused ? Color.blue : Color.clear, lineWidth: 3)
                        )
                        .scaleEffect(isFocused ? 1.08 : 1.0)
                }
            }

            Text(movie.title)
                .font(.caption)
                .lineLimit(2)
                .foregroundStyle(isFocused ? .white : .gray)
        }
        .onHover { hovering in
            withAnimation(.spring(response: 0.35)) {
                isFocused = hovering
            }
        }
        .onPlayPauseCommand {
            // Handling Play/Pause button on remote
            startPlayback()
        }
        .focusable()
        .focusEffect { phase in
            // Custom focus effect
            phase == .active ?
                AnyView(self.scaleEffect(1.08)) :
                AnyView(self.scaleEffect(1.0))
        }
    }

    private func startPlayback() {
        print("Playing: \(movie.title)")
    }
}

// // Main screen with movie grid
struct MovieGridScreen: View {
    let movies: [Movie]

    var body: some View {
        ScrollView {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 320, maximum: 400))], spacing: 24) {
                ForEach(movies) { movie in
                    MovieCardView(movie: movie)
                }
            }
            .padding(60)
        }
        .focusSection() // Grouping for navigation
    }
}

MovieCardView demonstrates Focus Engine in SwiftUI: the .focusable() modifier makes the element focusable, .onHover tracks state changes, .focusEffect allows custom focus animation. .onPlayPauseCommand handles the Play/Pause button press on Siri Remote. focusSection groups a grid for cyclic navigation.

Siri Remote: Gestures and Buttons

The second-generation Siri Remote (2021) has a touch surface, 5 buttons, and a microphone. tvOS supports gestures: swipes (navigation), tap (select), double-tap (center), pinch-zoom (images), long press (context menu). UIPress with types .select, .playPause, .menu, .upArrow, .downArrow, .leftArrow, .rightArrow — predefined press types. The remote microphone is used for Siri and voice search.

Top Shelf and App Screen

Top Shelf is an area on the Apple TV home screen that displays dynamic app content when the app is in the top row. In tvOS 17, Top Shelf supports up to 8 widgets with custom backgrounds and interactive elements. The developer implements TVTopShelfProvider to provide content.

Top Shelf Styles

Three Top Shelf styles are available: Sectioned — categorized list (series by genre), Inset — central element with detailed description (recommended movie), Photo — image grid (photo albums). The system updates Top Shelf in the background via BGTaskScheduler, similar to watchOS. The provider must return content quickly — tvOS caches data for 24 hours.

App Screen

The tvOS home screen consists of a Top Shelf row and an app grid. Users can rearrange icons and create folders. tvOS automatically unloads apps from memory when resources are low, so developers must properly handle UISceneDidDisconnectNotification and restore state upon relaunch.

Top Shelf StyleFormatWhen to Use
SectionedSections with headers and itemsSeries, podcasts, playlists
InsetOne large item with descriptionMovie of the day, exclusive
PhotoImage grid without captionsPhoto albums, galleries
TabTabs with switchingSports by type, news by topic

SwiftUI for Apple TV

SwiftUI is fully supported in tvOS starting from tvOS 13. Apple recommends SwiftUI for all new projects. The same SwiftUI code works on iOS, iPadOS, macOS, and tvOS with minimal adaptations for Focus Engine. SwiftUI for tvOS provides modifiers .focusable(), .focusSection(), .onPlayPauseCommand, and .onExitCommand.

tvOS Adaptation

When porting an iOS app to tvOS, you need to: replace TabView with NavigationView using focus-navigation, increase font sizes (minimum 30pt for headings, 22pt for body text), add margins (minimum 40pt from edges — safe area on TVs). tvOS does not support UIAlertController with text fields, UIWebView, or MFMailComposeViewController.

iOS ComponenttvOS EquivalentNote
UISliderUIProgressView + buttonsSlider not supported
UIPickerViewTable with focusPicker replaced by list
UITextFieldUIAlertController (read-only only)Text input via Siri
UIActionSheetUIAlertControllerSupported
UIWebViewNot supportedUse WKWebView
MFMailComposeNot supportedOpen mailto: URL

Design Recommendations

Apple HIG for tvOS: minimum touch area size 60×60 points, text readable from 3 meters (font size no less than 22pt for body), text contrast 4.5:1, dark background (light background glares on OLED TVs), all elements accessible without complex gestures. Resolution: Apple TV 4K outputs 3840×2160 (4K) or 1920×1080 (HD) at 60 FPS. All images should be @2x (for 1080p) and @4x (for 4K).

TVMLKit and Media Applications

TVMLKit — a framework for creating media apps on tvOS using web technologies: JavaScript (TVJS) and TVML (Apple-specific XML). TVMLKit apps do not require compilation — the interface loads from the server, allowing content updates without going through App Review. It is used by major streaming services for content carousels.

TVML: Template Structure

TVML provides ready-made templates: CatalogTemplate (catalog with sections), ProductTemplate (content detail page), FormTemplate (login forms), LoadingTemplate (loading indicator). Templates are described in XML and styled via CSS-like attributes. TVJS code handles presses and calls native APIs.

xml
<!-- CatalogTemplate — movie catalog on TVML -->
<document>
  <catalogTemplate>
    <banner>
      <title>New releases</title>
      <description>Fresh premieres and exclusives</description>
    </banner>
    <section>
      <header>
        <title>Popular</title>
      </header>
      <items>
        <lockup>
          <img src="https://cdn.example.com/movie1.jpg" width=300 height=450/>
          <title>Interstellar</title>
        </lockup>
        <lockup>
          <img src="https://cdn.example.com/movie2.jpg" width=300 height=450/>
          <title>Inception</title>
        </lockup>
      </items>
    </section>
  </catalogTemplate>
</document>

The TVML CatalogTemplate contains a banner with a title and sections with lockup elements. Each lockup is a movie card with an image and title. The Focus Engine automatically manages navigation between lockup elements. On press, the TVJS handler receives the select event and can display a detail page via ProductTemplate.

TVJS: Event Handling

TVJS is a JavaScript environment isolated from the main app. TVJS code is called when loading a TVML template and handling events. TVJS has access to native APIs via Appliance and Player for video playback control. Apple recommends using TVMLKit only for media apps with frequent content updates. For games and interactive apps, SwiftUI is preferred.

Publishing tvOS Apps

Publishing a tvOS app requires an Apple Developer Program subscription ($99/year). The app is uploaded via App Store Connect as a separate product or as part of a universal binary (iOS + tvOS). App Review checks stability, HIG compliance, and the 4 GB size limit.

Build and Distribution

Xcode creates a tvOS target with the .app extension (.ipa package). Architecture — arm64 (Apple TV uses Apple Silicon ARM chips). tvOS does not support frameworks with i386 or x86_64. The app is signed with an Apple Development certificate (testing) or Apple Distribution certificate (publication). Distribution via Volume Purchase Program for business clients is available.

App Review Requirements

Special tvOS requirements: all interface elements must be accessible via Focus Engine without using a touch screen or keyboard. Apps requiring authorization must support Single Sign-On (SSO) via iTunes Store. Advertising content cannot interrupt playback without user consent. Uploaded binary size must not exceed 4 GB.

RequirementDescription
App sizeNo more than 4 GB, recommended 500 MB
Graphics resolution@2x (1920×1080) and @4x (3840×2160) for 4K
Focus navigationAll elements reachable via Siri Remote
Video formatH.264, HEVC, Dolby Vision (Profile 5)
AudioDolby Atmos (E-AC-3 JOC) and stereo AAC

Frequently Asked Questions

What languages are used for tvOS development?

The primary language is Swift with SwiftUI and UIKit frameworks. For media apps, TVMLKit with JavaScript and TVML templates loaded from the server is used. Objective-C is supported for legacy projects. Apple recommends SwiftUI for all new tvOS projects.

How is tvOS different from iOS?

tvOS uses Focus Engine instead of touch events, has no camera or microphone (except Siri Remote), limits app size to 4 GB, does not support persistent local storage (purgeable), and requires Metal for rendering. All apps run only on ARM64.

How does Focus Engine work in tvOS?

Focus Engine manages focus movement between UI elements using the Siri Remote. The developer sets preferred focus via preferredFocusEnvironments. UIFocusHeading (up, down, left, right) determines direction. UIFocusEffect automatically adds parallax and shadow to the active element.

How to publish apps for Apple TV?

Publishing requires an Apple Developer Program subscription ($99/year). The app is uploaded via Xcode Organizer or Transporter to App Store Connect. Moderation checks: Focus Engine compatibility, stability, absence of UIWebView, and the 4 GB size limit.

Can UIKit be used in tvOS?

Yes, UIKit is fully supported in tvOS: UIView, UIViewController, UICollectionView, UITableView. However, UIKit is adapted for Focus Engine: UIButton and UIControl receive events via remote press, not touch. SwiftUI is recommended for new projects due to automatic focus adaptation.

Summary

  • tvOS — Apple's OS for TV set-top boxes on the XNU kernel with Focus Engine control
  • Focus Engine replaces touch control with focus movement via Siri Remote with parallax effects
  • TVMLKit — a unique framework for media apps in JavaScript with server-side TVML templates
  • Top Shelf provides dynamic content on the home screen via TVTopShelfProvider
  • SwiftUI is fully supported since tvOS 13 with focusable, focusSection, and onPlayPauseCommand modifiers
  • tvOS Limitations: 4 GB size, purgeable storage, no camera, UIWebView, or MFMailCompose
  • Publishing requires Apple Developer Program, @2x/@4x graphics, HEVC format, and Dolby Atmos

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also