Providing an integrated view of your timeline when playing HLS interstitials
At a glance
| Item | Summary |
|---|---|
| Purpose | Go beyond simple ad insertion with point and fill occupancy HLS interstitials. |
| App architecture | A Swift sample with the source-visible chain HLSInterstitialDemoApp → MenuView → ContentViewModel → AVFoundation APIs. |
| Main patterns | Model-View-ViewModel, Protocol-oriented abstraction, Delegate or data-source callbacks, Coordinator, Actor isolation |
| Project style | 30 scanned source file(s) across Swift, organized around ranked entry, type, and file boundaries. |
| Execution model | Source-visible boundaries: actor, Sendable or @Sendable, async declaration or closure, @MainActor, Task closure isolated to MainActor; none alone proves a background thread. |
| State/event model | Source-visible mechanisms: @Observable, SwiftUI state property wrapper, AnyCancellable, receive(on:). |
| Key frameworks/packages | Foundation, SwiftUI, AVFoundation, os, Observation; these are source dependencies, not architecture labels. |
Project structure
Source bundle/
└── HLSInterstitialDemo/
└── HLSInterstitialDemo/
├── HLSInterstitialDemoApp.swift
├── Menu/
│ ├── ViewModels/
│ │ ├── MenuItemViewModel.swift
│ │ ├── MenuItemLauncherViewModel.swift
│ │ ├── MenuSectionViewModel.swift
│ │ └── MenuViewModel.swift
│ └── Models/
│ └── Menu.swift
├── Helpers/
│ └── ModalPresentationCoordinator.swift
├── IntegratedTimeline/
│ ├── IntegratedTimelinePlayerView.swift
│ ├── IntegratedTimelinePlayingView.swift
│ └── Controls/
│ ├── ControlButtonStyleView.swift
│ └── PlaybackControlsView.swift
└── SharePlay/
└── SharePlayCoordinator.swift
Structure observations
- Architecturally prominent files are ranked from entry points and role-named declarations; resource-only paths are omitted.
- Primary languages: Swift.
- The verified tree contains 4 project/configuration file(s) and 42 source declaration(s).
Overall architecture
flowchart LR
N1["HLSInterstitialDemoApp"]
N2["MenuView"]
N3["ContentViewModel"]
N4["AVFoundation APIs"]
N1 --> N2
N2 --> N3
N3 --> N4
Reference code
HLSInterstitialDemo/HLSInterstitialDemo/HLSInterstitialDemoApp.swift:9 — architecture anchor
@main
struct HLSInterstitialDemoApp: App {
let menuViewModel = MenuViewModel.createViewModelWithMenu
var body: some Scene {
WindowGroup {
MenuView(viewModel: menuViewModel)
}
}
}Interpretation
The arrows summarize the source-visible entry, role-named types or folders, and framework direction; when nodes come from structural folders, the sequence is a high-level interpretation rather than proof that every adjacent node calls the next. Ownership is claimed only where the next section cites a stored property or assignment. The diagram is intentionally limited to the dominant path into AVFoundation.
Ownership and state
classDiagram
MenuItemViewModel o-- MenuItemViewModelDelegate : delegate
MenuItemViewModel o-- PlayerState : currentPlayerState
MenuItemViewModel o-- MenuItem : item
MenuItemViewModel o-- Contentviewmodel : contentViewModel
Ownership evidence
HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemViewModel.swift:18 — stored dependency or nearest verified ownership anchor
@Observable
class MenuItemViewModel: Identifiable, Hashable, MenuItemLauncherViewModelDelegate {
weak var delegate: MenuItemViewModelDelegate?
// ...
}| Owner | Object or state | Relationship | Mutation authority |
|---|---|---|---|
MenuItemViewModel |
MenuItemViewModelDelegate (delegate) |
holds a non-owning reference | The referenced object’s lifecycle is owned elsewhere |
MenuItemViewModel |
PlayerState (currentPlayerState) |
stores or receives | Owning lexical scope |
MenuItemViewModel |
MenuItem (item) |
stores or receives | Initialized by the owner; the binding is immutable |
MenuItemViewModel |
Contentviewmodel (contentViewModel) |
stores or receives | App/module collaborators |
Composition arrows indicate a source-visible construction expression or locally owned value state; aggregation means the owner stores or receives a dependency without proving exclusive lifetime ownership.
Concurrency, scheduling, and thread safety
Evidence limit: actor isolation, async/await, or Task creation does not by itself prove background-thread execution; Sendable conformance alone does not prove thread-safe mutation.
| Concern | Source mechanism | Verified placement or handoff | Evidence |
|---|---|---|---|
| Actor isolation | actor |
The cited type is actor-isolated; this does not select a background thread. | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:9 |
| Transfer contract | Sendable or @Sendable |
The source declares a sendability boundary; this alone does not synchronize mutable state. | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:9 |
| Suspension boundary | async declaration or closure |
The source declares or crosses an asynchronous boundary; it does not by itself establish background execution. | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:32 |
| Main isolation | @MainActor |
The cited annotation marks its attached declaration or closure as main-actor isolated. | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/ModalPresentationCoordinator.swift:32 |
| Main isolation | Task closure isolated to MainActor |
The cited operation explicitly enters a main-actor-isolated region. | HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemViewModel.swift:57 |
@MainActor/MainActor.run, DispatchQueue.main, and RunLoop.main are reported as distinct isolation, queue, and event-loop mechanisms. A plain Task is kept separate from Task.detached; neither is labeled as a background thread.
Reference code
HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:9 — representative execution boundary
public actor AsyncPassthroughValue<Element: Sendable>: AsyncSequence, AsyncIteratorProtocol {
// ...
case active
// ...
}State propagation, frameworks, and dependencies
Evidence limit: an import proves a source-level compilation dependency at the cited line; it does not prove runtime use, architectural adoption, or whether a Swift package is a direct application dependency.
| Category | Mechanism or module | Verified role | Evidence |
|---|---|---|---|
| State propagation | @Observable |
Observation macro publishes source-visible changes. | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/ModalPresentationCoordinator.swift:18 |
| State propagation | SwiftUI state property wrapper |
A SwiftUI property wrapper supplies or observes UI state. | HLSInterstitialDemo/HLSInterstitialDemo/IntegratedTimeline/Controls/TransportBarView.swift:23 |
| State propagation | AnyCancellable |
A cancellable value records subscription lifetime management. | HLSInterstitialDemo/HLSInterstitialDemo/PlayerState.swift:19 |
| Combine scheduling | receive(on:) |
receive(on:) selects the scheduler for downstream delivery. |
HLSInterstitialDemo/HLSInterstitialDemo/PlayerState.swift:188 |
| Source import | Foundation |
The cited file imports this module; runtime use and architectural role are not inferred. | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:7 |
| Source import | SwiftUI |
The cited file imports this module; runtime use and architectural role are not inferred. | HLSInterstitialDemo/HLSInterstitialDemo/HLSInterstitialDemoApp.swift:7 |
| Source import | AVFoundation |
The cited file imports this module; runtime use and architectural role are not inferred. | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/Extensions/AVPlayerInterstitialEvent+Additions.swift:7 |
| Source import | os |
The cited file imports this module; runtime use and architectural role are not inferred. | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/Extensions/Bundle+Additions.swift:8 |
receive(on:) describes downstream delivery scheduling, while subscribe(on:) describes upstream subscription/request/cancel scheduling. An import Combine alone establishes neither behavior nor a Store, reducer, Redux, or other application architecture.
Class and protocol design
HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemViewModel.swift:12 — representative type boundary
protocol MenuItemViewModelDelegate: AnyObject {
func menuItemViewModelWantsToBePlayed(_ itemViewModel: MenuItemViewModel)
}| Type | Responsibility | Depends on or conforms to |
|---|---|---|
HLSInterstitialDemoApp |
Application entry and top-level composition | App |
MenuItemViewModelDelegate |
Defines a capability or collaboration contract | AnyObject |
MenuItemLauncherViewModelDelegate |
Defines a capability or collaboration contract | AnyObject |
MenuSectionViewModelDelegate |
Defines a capability or collaboration contract | AnyObject |
MenuItemViewModel |
UI-facing state and feature coordination | Identifiable, Hashable, MenuItemLauncherViewModelDelegate |
ContentViewModel |
UI-facing state and feature coordination | Concrete collaborators/imported frameworks |
MenuItemLauncherViewModel |
UI-facing state and feature coordination | Concrete collaborators/imported frameworks |
MenuSectionViewModel |
UI-facing state and feature coordination | Identifiable, MenuItemViewModelDelegate |
MenuViewModel |
UI-facing state and feature coordination | MenuSectionViewModelDelegate |
ModalPresentationCoordinator |
Cross-object flow or session coordination | Concrete collaborators/imported frameworks |
The source explicitly defines local protocol relationships: MenuItemViewModel → MenuItemLauncherViewModelDelegate, MenuSectionViewModel → MenuItemViewModelDelegate, MenuViewModel → MenuSectionViewModelDelegate.
Access control
| Symbol | Access | Verified effect | Likely rationale |
|---|---|---|---|
AsyncPassthroughValue (HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:27) |
public |
The symbol is visible to importing modules. | Inference: make the declaration available across a module or target boundary. |
next (HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:32) |
public |
The symbol is visible to importing modules. | Inference: make the declaration available across a module or target boundary. |
send (HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:54) |
public |
The symbol is visible to importing modules. | Inference: make the declaration available across a module or target boundary. |
finish (HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:74) |
public |
The symbol is visible to importing modules. | Inference: make the declaration available across a module or target boundary. |
Reference code
HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:27 — representative boundary
public init(_ elementType: Element.Type = Element.self) {
state = .active
}Swift declarations without a modifier are internal; explicit private, fileprivate, private(set), public, or open entries above are interpreted by language semantics. Objective-C/C samples instead rely on header and implementation boundaries, which are not equivalent to Swift lexical privacy.
Logic ownership and placement
| Logic | Owning type or file | Placement rationale |
|---|---|---|
| Application entry and top-level composition | HLSInterstitialDemoApp |
The source’s App suffix makes this role explicit. |
| Cross-object flow or session coordination | ModalPresentationCoordinator, SharePlayCoordinator |
The source’s Coordinator suffix makes this role explicit. |
| Receives callback-driven events | MenuItemLauncherViewModelDelegate, MenuItemViewModelDelegate, MenuSectionViewModelDelegate, PlayerCoordinatorDelegate |
The source’s Delegate suffix makes this role explicit. |
| User-interface presentation and input forwarding | FillOccupancyView, IntegratedTimelinePlayerView, IntegratedTimelinePlayingUIView, IntegratedTimelinePlayingView |
The source’s View suffix makes this role explicit. |
| UI-facing state and feature coordination | ContentViewModel, MenuItemLauncherViewModel, MenuItemViewModel, MenuSectionViewModel |
The source’s ViewModel suffix makes this role explicit. |
Design patterns
| Pattern | Source evidence | Purpose or tradeoff |
|---|---|---|
| Model-View-ViewModel | HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemViewModel.swift:98 |
Role-named view models keep UI-facing state or coordination outside view declarations. |
| Protocol-oriented abstraction | HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemViewModel.swift:17 |
A local protocol and concrete conformance create an explicit capability boundary. |
| Delegate or data-source callbacks | HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemViewModel.swift:17 |
Callback protocols invert event delivery back into the sample’s owner. |
| Coordinator | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/ModalPresentationCoordinator.swift:19 |
A role-named coordinator centralizes cross-object flow. |
| Actor isolation | HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift:9 |
A declared actor creates an explicit isolation boundary; its executor is not described as a background thread. |
Naming conventions
- Types: App: HLSInterstitialDemoApp; Coordinator: ModalPresentationCoordinator, SharePlayCoordinator; Delegate: MenuItemLauncherViewModelDelegate, MenuItemViewModelDelegate, MenuSectionViewModelDelegate, PlayerCoordinatorDelegate; View: FillOccupancyView, IntegratedTimelinePlayerView, IntegratedTimelinePlayingUIView, IntegratedTimelinePlayingView, MenuItemLauncherView; ViewModel: ContentViewModel, MenuItemLauncherViewModel, MenuItemViewModel, MenuSectionViewModel, MenuViewModel.
- Protocols:
MenuItemViewModelDelegate,MenuItemLauncherViewModelDelegate,MenuSectionViewModelDelegate. - Methods:
menuItemViewModelWantsToBePlayed,hash,dismissActiveContent,presentPlayer,menuItemLauncherViewModelWantsToBePlayed,play,menuSectionViewModel,encode. - Files:
HLSInterstitialDemo/HLSInterstitialDemo/HLSInterstitialDemoApp.swift,HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemViewModel.swift,HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemLauncherViewModel.swift,HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuSectionViewModel.swift,HLSInterstitialDemo/HLSInterstitialDemo/Menu/Models/Menu.swift,HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuViewModel.swift.
Architecture takeaways
HLSInterstitialDemoAppis the main source-visible entry or composition anchor for this sample.- Framework work reaches SwiftUI, AVFoundation, GroupActivities, AVFAudio through a deliberately small high-level chain; the detailed API graph remains inside the cited implementation files.
- Stored-property evidence identifies lifecycle collaboration; it does not by itself prove exclusive object ownership.
- Access-control conclusions separate verified language visibility from the likely design rationale.
- Local protocol relationships provide an explicit substitution boundary.
Source map
| Source file | Relevant symbols |
|---|---|
HLSInterstitialDemo/HLSInterstitialDemo/HLSInterstitialDemoApp.swift |
Cited implementation, SwiftUI, HLSInterstitialDemoApp |
HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemViewModel.swift |
Cited implementation, MenuItemViewModelDelegate, ContentViewModel, Task closure isolated to MainActor, MenuItemViewModel |
HLSInterstitialDemo/HLSInterstitialDemo/Helpers/AsyncPassthroughValue.swift |
Cited implementation, AsyncPassthroughValue, actor, Sendable or @Sendable, async declaration or closure, Foundation, State |
HLSInterstitialDemo/HLSInterstitialDemo/Helpers/ModalPresentationCoordinator.swift |
ModalPresentationCoordinator, @MainActor, @Observable, ModalPresentation, ModalPresentationCoordViewModifier |
HLSInterstitialDemo/HLSInterstitialDemo/IntegratedTimeline/Controls/TransportBarView.swift |
SwiftUI state property wrapper, TransportBarView |
HLSInterstitialDemo/HLSInterstitialDemo/PlayerState.swift |
AnyCancellable, receive(on:), PlayerState |
HLSInterstitialDemo/HLSInterstitialDemo/Helpers/Extensions/AVPlayerInterstitialEvent+Additions.swift |
AVFoundation, EventStart |
HLSInterstitialDemo/HLSInterstitialDemo/Helpers/Extensions/Bundle+Additions.swift |
os, DecodingError |
HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuItemLauncherViewModel.swift |
MenuItemLauncherViewModelDelegate, MenuItemLauncherViewModel |
HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuSectionViewModel.swift |
MenuSectionViewModelDelegate, MenuSectionViewModel |
HLSInterstitialDemo/HLSInterstitialDemo/Menu/Models/Menu.swift |
Menu, MenuSection, MenuItem, PlaybackBehaviors, InterstitialEvent, CueType, OccupancyType |
HLSInterstitialDemo/HLSInterstitialDemo/Menu/ViewModels/MenuViewModel.swift |
MenuViewModel |
HLSInterstitialDemo/HLSInterstitialDemo/IntegratedTimeline/IntegratedTimelinePlayerView.swift |
IntegratedTimelinePlayerView, IgnoreSafeAreaModifier |
HLSInterstitialDemo/HLSInterstitialDemo/IntegratedTimeline/IntegratedTimelinePlayingView.swift |
IntegratedTimelinePlayingView, IntegratedTimelinePlayingUIView |
HLSInterstitialDemo/HLSInterstitialDemo/SharePlay/SharePlayCoordinator.swift |
SharePlayCoordinator, SharedContent |
HLSInterstitialDemo/HLSInterstitialDemo/IntegratedTimeline/Controls/ControlButtonStyleView.swift |
ControlButton |