tvOS Integration Skill
Integration conventions for the StreamLayer tvOS SDK that keep an AI agent's diff small and correct — where to initialize, the tvOS-specific createOverlay, delegate wiring, focus/remote, and ad breaks.
StreamLayer tvOS SDK Integration
How to wire StreamLayer into an existing tvOS app cleanly. Follow the rules —
they prevent the common over-integration mistakes.
This page is the human-readable form of the streamlayer-tvos-integration agent
skill. Reference it from your AI agent alongside the streamlayer-docs MCP — see
Integrate with an AI Agent.
The tvOS SDK shares the iOS SDKtvOS ships in the same
StreamLayerpackage as iOS. For anything not called out
as tvOS-specific below, follow the iOS Integration Guide.
Pick the package
StreamLayer— the SDK, distributed as a dynamic framework via Swift
Package Manager ([email protected]:StreamLayer/sdk-ios.git, product
StreamLayer). Add the package, thenimport StreamLayerSDKTVOS(the tvOS
module — notStreamLayerSDK).- Main UI element: the StreamLayer Element, created with
StreamLayer.createOverlay(containerViewController:contentView:delegate:)and
rendered on top of your player. - Requirements: Xcode 16+, Swift 6, tvOS 18+.
Rules (do this)
-
Initialize once at launch; create the overlay in the player screen. Call
StreamLayer.initSDK(with: key)exactly once at app launch (AppDelegate),
then start your event withStreamLayer.createSession(for: eventId)after
authentication completes. Build the
Element in the view controller that owns the video — via
createOverlay(containerViewController:contentView:delegate:). Note the tvOS
signature differs from iOS: you pass your content view (the video
container) and aStreamLayerTVOSDelegate, not the iOS overlay-delegate set.- ❌ Copying the iOS
createOverlay(mainContainerViewController:overlayDelegate:…)call shape. - ✅
createOverlay(containerViewController: self, contentView: playerView, delegate: self).
- ❌ Copying the iOS
-
Implement
StreamLayerTVOSDelegatefor the player bridge. It has three
methods:streamLayerDelegateUpdateDuckingState(_ enabled: Bool, fullyMuteHost: Bool)
— lower your player volume whenenabledistrue(to zero when
fullyMuteHostistrue) and restore it whenfalse. It has a default
implementation, so a one-argument version compiles but is never called; the
requiredstreamLayerDelegateAdDidFinish(_ info: SLRAdInfo)— resume playback
wheninfo.isPausedAdistrue; and the optional
streamLayerDelegateAdDidStart(_ info: SLRAdInfo). Keep a strong owner of the
delegate so callbacks keep firing. -
Let the SDK own focus and the remote. On tvOS the SDK handles Apple TV
remote navigation and the focus engine for its Element automatically. Don't
fight it — don't trap focus, don't intercept remote presses meant for the
overlay while it's active, and keep your own focus guides outside the Element's
region. Restore your normal focus environment after the Element dismisses. -
Drive ad breaks and the stream timeline. Call
StreamLayer.startADBreak()
/StreamLayer.stopADBreak()around your ad breaks, and
StreamLayer.setStreamTimelineEnabled(_:player:)to feed stream time for
spoiler-safe and timed units. For server-side ad insertion, set
StreamLayer.shared.ssaiHostDelegateto react towillBeginAdBreak/
didFinishAdBreak. Wire only what your app actually uses. -
Auth + credentials. Authenticate once after init —
try await StreamLayer.setAnonymousAuth(), thencreateSession. The tvOS
module has no bypass-token call — don't copy the iOS
setAuthorizationBypass(token:schema:)oruseAnonymousAuth(). The SDK API
Key is a public, client-side value from StreamLayer Studio
— a constant is fine; don't add.envscaffolding. User tokens are different:
never hardcode them. Keep the diff minimal: fit
the Element around your existing player screen instead of restructuring it.
Gotchas
createOverlaysignature is different from iOS. tvOS takescontentView+
StreamLayerTVOSDelegate; don't copy the iOS overlay-delegate call.- Wrong import. Use
import StreamLayerSDKTVOS, notStreamLayerSDK. initSDKcalled twice traps — it's a one-time call.createOverlaybeforeinitSDKcrashes. It dereferences the SDK
singleton, so a lazy overlay property touched before init brings the app down.- Left-ducked audio. Always restore player volume when
streamLayerDelegateUpdateDuckingStateis called withenabled == false; forgetting to leaves the stream
quiet after an ad or voice segment. - Focus traps. The most common tvOS pitfall — don't override
preferredFocusEnvironmentsin a way that steals focus from the active Element. - Shared SDK. For dependencies, SDK API Key, and initialization mechanics not
covered here, follow the iOS Integration Guide. - Authoritative API details: the
streamlayer-docsMCP (search/fetch) and
the tvOS docs.
Related
- Integrate with an AI Agent — Connect the MCP and prompt your agent to run this integration
- tvOS Getting Started — tvOS setup, requirements, and installation
- iOS Integration Guide — The shared SDK setup the tvOS SDK builds on
- Pause Advertising — Display ads when the viewer pauses playback
- Custom Paused Ads — Fullscreen and transparent pause ads with VAST
Updated 24 days ago
