iOS Integration Skill
Integration conventions for the StreamLayer iOS SDK that keep an AI agent's diff small and correct — where to initialize, where to create the overlay, delegate wiring, and minimal-diff placement.
StreamLayer iOS SDK Integration
How to wire StreamLayer into an existing UIKit app cleanly. Follow the rules —
they prevent the common over-integration mistakes.
This page is the human-readable form of the streamlayer-ios-integration agent
skill. Reference it from your AI agent alongside the streamlayer-docs MCP — see
Integrate with an AI Agent.
Pick the package
StreamLayer— the iOS SDK, distributed as a dynamic framework via Swift
Package Manager ([email protected]:StreamLayer/sdk-ios.git, product
StreamLayer). Add the package, thenimport StreamLayerSDK.- Main UI element:
SLRWidgetsViewController— the StreamLayer Element,
created withStreamLayer.createOverlay(...)and embedded over your player. - Optional plugins (separate package,
github.com/StreamLayer/sdk-ios-plugins):StreamLayerSDKPluginsGooglePAL,
StreamLayerSDKPluginsPermissions,StreamLayerSDKPluginsWatchParty— install
only the ones you need. - Requirements: Xcode 16+, Swift 6, iOS 15+.
Rules (do this)
-
Initialize once and high; create the overlay low. Call
StreamLayer.initSDK(with:delegate:loggerDelegate:)exactly once at app launch
(AppDelegate.application(_:didFinishLaunchingWithOptions:)), after setting any
StreamLayer.config.*options. Create the StreamLayer Element
(StreamLayer.createOverlay(...)) inside the player screen's view
controller — the one that owns the video and its play/pause state — not in the
app delegate, and not as a global singleton view.- ❌
initSDKinside the player view controller; ❌createOverlayin the app delegate. - ✅
initSDKinAppDelegate;createOverlaylazily in the player view controller.
- ❌
-
Add the overlay as a child view controller, pinned over your player
container.createOverlayreturns anSLRWidgetsViewController. Add it with
addChild/didMove(toParent:)and pin its view to the container that holds
the video — not the whole window. Put your own content on acontainerViewyou
own and callcontainerView.addSubview(...), notview.addSubview(...), so the
SDK can resize the container for sidebar / L-bar layouts. One overlay instance
per player screen. -
Drive layout with
setNeedsLayout(); wire only the delegates your features
use. CallStreamLayer.setNeedsLayout()fromviewDidLayoutSubviews()and
after rotations / size transitions so the Element re-lays out. Implement
SLROverlayDelegatefor the player bridge (audio ducking,pauseVideo/
playVideo,getPlayerVolume/setPlayerVolume,switchStream) — all
methods are optional; wire the ones your app needs and leave the rest. Add
SLROverlayDataSource.overlayHeight()for vertical placement, and
SLRSideBarDelegateonly if you enableStreamLayer.config.overlayMode = .sidebar. -
Forward authentication after init. For logged-in users, call
StreamLayer.setAuthorizationBypass(token:schema:)with a token from your
backend; for demos or guests useStreamLayer.useAnonymousAuth(). Do it once,
afterinitSDK. Follow the documented auth-forwarding flow rather than
inventing a login screen. Start a session for your event with
StreamLayer.createSession(for: eventId)in the player screen. -
Keep credentials and the diff simple. The SDK API Key is a public,
client-side value from StreamLayer Studio
— a constant or your existing config is fine; don't add.envscaffolding or
dev-only warnings. Fit the overlay around your existing player and layout —
don't restructure the app, add wrapper view controllers, or refactor unrelated
view code. Register optional plugins (registerPALPlugin,
registerPermissionsPlugin,registerWatchPartyPlugin) before use, and only
the ones you need.
Gotchas
- StreamLayer Element not showing. Almost always a missing
StreamLayer.setNeedsLayout()after a layout / rotation change, or the widgets
view added toviewinstead of thecontainerViewthe SDK resizes. initSDKcalled twice traps — it's a one-time call. Guard against re-init
across multiple scenes or SwiftUI previews.- Delegate methods not firing. The delegate / data source must be assigned
when you callcreateOverlay, and must have a strong owner — a deallocated
delegate silently stops callbacks. - iPad-only surfaces. Some paused-ad variants render on iPad only (see the
Exposed Ads section of the API Reference); don't rely on
them on iPhone. - Internal architecture is not your concern. VIPER, RxSwift, and the DI
container are SDK internals — you only touch theStreamLayerfacade, its
delegates, andStreamLayer.config. Don't try to subclass or reach into them. - Authoritative API details: the
streamlayer-docsMCP (search/fetch) and
the API Reference.
Related
- Integrate with an AI Agent — Connect the MCP and prompt your agent to run this integration
- Integration Guide — Complete iOS SDK setup and configuration
- SLROverlayDelegate — The player-bridge delegate contract in full
- Authentication Forwarding — The documented auth-forwarding flow
- API Reference — Every public class, method, and enum
Updated 20 days ago
