Skip to content

Releases: lessthan3/MaestroKit.android

paramountKit 4.0.9.149

24 Apr 13:06
d8e8149

Choose a tag to compare

paramountKit

Kotlin Multiplatform framework for the Maestro Paramount SDK — exposes Stats (live MMA/UFC data), Key Plays (Key Moments), and animated Overlays to tvOS and iOS apps via Swift Package Manager.

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/lessthan3/MaestroKit.android", from: "4.0.0")
]

Platforms

  • tvOS 16+
  • iOS 16+

Quick Start

import paramountKit

// 1. Configure the SDK once per session.
let instance = ParamountMaestroSDK.shared.configure(
    context: PlatformContext(),
    delegate: MyParamountDelegate(),
    params: ParamountSDKParameters(
        siteId: "your-site-id",
        pageId: nil,
        metadataValue: "event-metadata-value",
        appPackageVersion: "1.0.0",
        isProduction: true,
        userAgent: "ATV"
    ),
    buildConfigInfo: ParamountBuildConfigInfo(
        versionName: "1.0.0",
        isDebug: false
    )
)

// 2. Observe available panels (Stats, Key Plays, Builder) from the config.
Task {
    for await panels in instance.repo.enabledPanels {
        print("Panels: \((panels as? [SharedPanelData])?.map { $0.name } ?? [])")
    }
}

// 3. Tell the SDK which panel is currently shown (for analytics + gating).
instance.didShowPanel(panelTypeId: ParamountPanelTypes.shared.STATS)

// 4. Detach when done.
instance.detach()

Delegate

ParamountEventDelegate is how the SDK talks back to the host app:

class MyParamountDelegate: ParamountEventDelegate {
    func shouldShowPanel() { /* host should surface the panel UI */ }
    func shouldHidePanel() { /* host should hide it */ }
    func trackAction(analytics: [String: String]) { /* forward to your analytics */ }
    func trackImpression(analytics: [String: String]) { /* forward to your analytics */ }
    func onKeyMomentSelected(contentId: String) { /* play the clip */ }
}

Features

Stats panel (MMA/UFC)

Fetches live fight data from the Helios supergraph, polls every 10s, retries with backoff.

let stats = instance.createStatsPresenter()
stats.start()

Task {
    for await state in stats.state {
        switch onEnum(of: state) {
        case .loading:
            print("Loading fights…")
        case .error(let e):
            print("Error: \(e.message)")
        case .success(let s):
            let event = s.event
            print("\(event.name) at \(event.venue)")
            for fight in event.fights {
                print("  \(fight.redFighter.lastName) vs \(fight.blueFighter.lastName)")
            }
        }
    }
}

stats.destroy()

Key Plays panel (Key Moments)

Host app pushes key-moment data into the SDK; the presenter handles sort order + playback progress.

let keyPlays = instance.createKeyPlaysPresenter()
keyPlays.start()

// Push moments from your backend.
instance.updateKeyMomentsData(data: [
    ParamountKeyMoment(contentId: "clip-1", title: "Round 1 KO", ...)
])

// Update playback progress as the user watches.
instance.updateKeyMomentsProgress(contentId: "clip-1", progress: 0.42)

// Change sort order.
instance.setKeyMomentsSortOrder(sortOrder: KeyMomentsSortOrder.newestFirst)

Task {
    for await state in keyPlays.state {
        print("\(state.moments.count) moments, active=\(state.activeContentId ?? "none")")
    }
}

keyPlays.destroy()

Animated Overlays

Rive-based broadcast overlays driven by the SDK's overlay queue.

let overlays = instance.createOverlayPresenter()
overlays.start()

Task {
    for await event in overlays.events {
        // event carries the Rive file URL + duration.
    }
}

overlays.destroy()

Type mapping

Kotlin Swift
StateFlow<T> AsyncSequence — consume with for await
sealed interface / sealed class Use switch onEnum(of:) for exhaustive matching
data object Foo FooType.shared singleton
List<T> Array<T>
Long Int64

Sealed state pattern

switch onEnum(of: state) {
case .loading:
    ProgressView()
case .error(let e):
    Text(e.message)
case .success(let s):
    ContentView(event: s.event)
}

Working example

A complete SwiftUI demo lives in demos/demo-tvos-paramount/ in this repo. It wires up Stats, Key Plays, Overlays, and the panel-visibility bridge.

License

Copyright (c) LessThan3


Installation

.binaryTarget(
    name: "paramountKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/paramountKit-4.0.9.149/paramountKit-4.0.9.149.zip",
    checksum: "69900b18a3ac205069ba7efd9b87f093267ca32cfaa8a68c55f4819271068de8"
)

foxKit 4.0.9.150

24 Apr 15:31
d8e8149

Choose a tag to compare

Installation

.binaryTarget(
    name: "foxKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/foxKit-4.0.9.150/foxKit-4.0.9.150.zip",
    checksum: "6abff1e348f17ba7a80caf18e693b1e7cb02cd545618b08095b25e089c828ba4"
)

foxKit 4.0.9.149

24 Apr 13:05
ff9d652

Choose a tag to compare

Installation

.binaryTarget(
    name: "foxKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/foxKit-4.0.9.149/foxKit-4.0.9.149.zip",
    checksum: "0286f39eef22672c3a4a3f527cca6ec11f758cf3ad8352e1ee82647230d9bdf1"
)

foxKit 4.0.9.148

23 Apr 14:33
6978c78

Choose a tag to compare

Installation

.binaryTarget(
    name: "foxKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/foxKit-4.0.9.148/foxKit-4.0.9.148.zip",
    checksum: "cc301355d7f82c803604081d18104fc8a9ac0f9bbf44b7ca2c2febcfff55ee12"
)

paramountKit 4.0.9.147

23 Apr 12:44
a91c41c

Choose a tag to compare

paramountKit

Kotlin Multiplatform framework for the Maestro Paramount SDK — exposes Stats (live MMA/UFC data), Key Plays (Key Moments), and animated Overlays to tvOS and iOS apps via Swift Package Manager.

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/lessthan3/MaestroKit.android", from: "4.0.0")
]

Platforms

  • tvOS 16+
  • iOS 16+

Quick Start

import paramountKit

// 1. Configure the SDK once per session.
let instance = ParamountMaestroSDK.shared.configure(
    context: PlatformContext(),
    delegate: MyParamountDelegate(),
    params: ParamountSDKParameters(
        siteId: "your-site-id",
        pageId: nil,
        metadataValue: "event-metadata-value",
        appPackageVersion: "1.0.0",
        isProduction: true,
        userAgent: "ATV"
    ),
    buildConfigInfo: ParamountBuildConfigInfo(
        versionName: "1.0.0",
        isDebug: false
    )
)

// 2. Observe available panels (Stats, Key Plays, Builder) from the config.
Task {
    for await panels in instance.repo.enabledPanels {
        print("Panels: \((panels as? [SharedPanelData])?.map { $0.name } ?? [])")
    }
}

// 3. Tell the SDK which panel is currently shown (for analytics + gating).
instance.didShowPanel(panelTypeId: ParamountPanelTypes.shared.STATS)

// 4. Detach when done.
instance.detach()

Delegate

ParamountEventDelegate is how the SDK talks back to the host app:

class MyParamountDelegate: ParamountEventDelegate {
    func shouldShowPanel() { /* host should surface the panel UI */ }
    func shouldHidePanel() { /* host should hide it */ }
    func trackAction(analytics: [String: String]) { /* forward to your analytics */ }
    func trackImpression(analytics: [String: String]) { /* forward to your analytics */ }
    func onKeyMomentSelected(contentId: String) { /* play the clip */ }
}

Features

Stats panel (MMA/UFC)

Fetches live fight data from the Helios supergraph, polls every 10s, retries with backoff.

let stats = instance.createStatsPresenter()
stats.start()

Task {
    for await state in stats.state {
        switch onEnum(of: state) {
        case .loading:
            print("Loading fights…")
        case .error(let e):
            print("Error: \(e.message)")
        case .success(let s):
            let event = s.event
            print("\(event.name) at \(event.venue)")
            for fight in event.fights {
                print("  \(fight.redFighter.lastName) vs \(fight.blueFighter.lastName)")
            }
        }
    }
}

stats.destroy()

Key Plays panel (Key Moments)

Host app pushes key-moment data into the SDK; the presenter handles sort order + playback progress.

let keyPlays = instance.createKeyPlaysPresenter()
keyPlays.start()

// Push moments from your backend.
instance.updateKeyMomentsData(data: [
    ParamountKeyMoment(contentId: "clip-1", title: "Round 1 KO", ...)
])

// Update playback progress as the user watches.
instance.updateKeyMomentsProgress(contentId: "clip-1", progress: 0.42)

// Change sort order.
instance.setKeyMomentsSortOrder(sortOrder: KeyMomentsSortOrder.newestFirst)

Task {
    for await state in keyPlays.state {
        print("\(state.moments.count) moments, active=\(state.activeContentId ?? "none")")
    }
}

keyPlays.destroy()

Animated Overlays

Rive-based broadcast overlays driven by the SDK's overlay queue.

let overlays = instance.createOverlayPresenter()
overlays.start()

Task {
    for await event in overlays.events {
        // event carries the Rive file URL + duration.
    }
}

overlays.destroy()

Type mapping

Kotlin Swift
StateFlow<T> AsyncSequence — consume with for await
sealed interface / sealed class Use switch onEnum(of:) for exhaustive matching
data object Foo FooType.shared singleton
List<T> Array<T>
Long Int64

Sealed state pattern

switch onEnum(of: state) {
case .loading:
    ProgressView()
case .error(let e):
    Text(e.message)
case .success(let s):
    ContentView(event: s.event)
}

Working example

A complete SwiftUI demo lives in demos/demo-tvos-paramount/ in this repo. It wires up Stats, Key Plays, Overlays, and the panel-visibility bridge.

License

Copyright (c) LessThan3


Installation

.binaryTarget(
    name: "paramountKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/paramountKit-4.0.9.147/paramountKit-4.0.9.147.zip",
    checksum: "cc9c761800df2d99713c7286d33d6ce648604b8940438e3765fc41bdfc679565"
)

paramountKit 4.0.8.146

22 Apr 18:39
fc6946b

Choose a tag to compare

paramountKit

Kotlin Multiplatform framework for the Maestro Paramount SDK — exposes Stats (live MMA/UFC data), Key Plays (Key Moments), and animated Overlays to tvOS and iOS apps via Swift Package Manager.

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/lessthan3/MaestroKit.android", from: "4.0.0")
]

Platforms

  • tvOS 16+
  • iOS 16+

Quick Start

import paramountKit

// 1. Configure the SDK once per session.
let instance = ParamountMaestroSDK.shared.configure(
    context: PlatformContext(),
    delegate: MyParamountDelegate(),
    params: ParamountSDKParameters(
        siteId: "your-site-id",
        pageId: nil,
        metadataValue: "event-metadata-value",
        appPackageVersion: "1.0.0",
        isProduction: true,
        userAgent: "ATV"
    ),
    buildConfigInfo: ParamountBuildConfigInfo(
        versionName: "1.0.0",
        isDebug: false
    )
)

// 2. Observe available panels (Stats, Key Plays, Builder) from the config.
Task {
    for await panels in instance.repo.enabledPanels {
        print("Panels: \((panels as? [SharedPanelData])?.map { $0.name } ?? [])")
    }
}

// 3. Tell the SDK which panel is currently shown (for analytics + gating).
instance.didShowPanel(panelTypeId: ParamountPanelTypes.shared.STATS)

// 4. Detach when done.
instance.detach()

Delegate

ParamountEventDelegate is how the SDK talks back to the host app:

class MyParamountDelegate: ParamountEventDelegate {
    func shouldShowPanel() { /* host should surface the panel UI */ }
    func shouldHidePanel() { /* host should hide it */ }
    func trackAction(analytics: [String: String]) { /* forward to your analytics */ }
    func trackImpression(analytics: [String: String]) { /* forward to your analytics */ }
    func onKeyMomentSelected(contentId: String) { /* play the clip */ }
}

Features

Stats panel (MMA/UFC)

Fetches live fight data from the Helios supergraph, polls every 10s, retries with backoff.

let stats = instance.createStatsPresenter()
stats.start()

Task {
    for await state in stats.state {
        switch onEnum(of: state) {
        case .loading:
            print("Loading fights…")
        case .error(let e):
            print("Error: \(e.message)")
        case .success(let s):
            let event = s.event
            print("\(event.name) at \(event.venue)")
            for fight in event.fights {
                print("  \(fight.redFighter.lastName) vs \(fight.blueFighter.lastName)")
            }
        }
    }
}

stats.destroy()

Key Plays panel (Key Moments)

Host app pushes key-moment data into the SDK; the presenter handles sort order + playback progress.

let keyPlays = instance.createKeyPlaysPresenter()
keyPlays.start()

// Push moments from your backend.
instance.updateKeyMomentsData(data: [
    ParamountKeyMoment(contentId: "clip-1", title: "Round 1 KO", ...)
])

// Update playback progress as the user watches.
instance.updateKeyMomentsProgress(contentId: "clip-1", progress: 0.42)

// Change sort order.
instance.setKeyMomentsSortOrder(sortOrder: KeyMomentsSortOrder.newestFirst)

Task {
    for await state in keyPlays.state {
        print("\(state.moments.count) moments, active=\(state.activeContentId ?? "none")")
    }
}

keyPlays.destroy()

Animated Overlays

Rive-based broadcast overlays driven by the SDK's overlay queue.

let overlays = instance.createOverlayPresenter()
overlays.start()

Task {
    for await event in overlays.events {
        // event carries the Rive file URL + duration.
    }
}

overlays.destroy()

Type mapping

Kotlin Swift
StateFlow<T> AsyncSequence — consume with for await
sealed interface / sealed class Use switch onEnum(of:) for exhaustive matching
data object Foo FooType.shared singleton
List<T> Array<T>
Long Int64

Sealed state pattern

switch onEnum(of: state) {
case .loading:
    ProgressView()
case .error(let e):
    Text(e.message)
case .success(let s):
    ContentView(event: s.event)
}

Working example

A complete SwiftUI demo lives in demos/demo-tvos-paramount/ in this repo. It wires up Stats, Key Plays, Overlays, and the panel-visibility bridge.

License

Copyright (c) LessThan3


Installation

.binaryTarget(
    name: "paramountKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/paramountKit-4.0.8.146/paramountKit-4.0.8.146.zip",
    checksum: "88768eca3bbf64f7a1947cbc2b2c5da48049c20661e9e07c79653b6eb33dd7f1"
)

paramountKit 4.0.8.145

22 Apr 17:47
be20d11

Choose a tag to compare

paramountKit

Kotlin Multiplatform framework for the Maestro Paramount SDK — exposes Stats (live MMA/UFC data), Key Plays (Key Moments), and animated Overlays to tvOS and iOS apps via Swift Package Manager.

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/lessthan3/MaestroKit.android", from: "4.0.0")
]

Platforms

  • tvOS 16+
  • iOS 16+

Quick Start

import paramountKit

// 1. Configure the SDK once per session.
let instance = ParamountMaestroSDK.shared.configure(
    context: PlatformContext(),
    delegate: MyParamountDelegate(),
    params: ParamountSDKParameters(
        siteId: "your-site-id",
        pageId: nil,
        metadataValue: "event-metadata-value",
        appPackageVersion: "1.0.0",
        isProduction: true,
        userAgent: "ATV"
    ),
    buildConfigInfo: ParamountBuildConfigInfo(
        versionName: "1.0.0",
        isDebug: false
    )
)

// 2. Observe available panels (Stats, Key Plays, Builder) from the config.
Task {
    for await panels in instance.repo.enabledPanels {
        print("Panels: \((panels as? [SharedPanelData])?.map { $0.name } ?? [])")
    }
}

// 3. Tell the SDK which panel is currently shown (for analytics + gating).
instance.didShowPanel(panelTypeId: ParamountPanelTypes.shared.STATS)

// 4. Detach when done.
instance.detach()

Delegate

ParamountEventDelegate is how the SDK talks back to the host app:

class MyParamountDelegate: ParamountEventDelegate {
    func shouldShowPanel() { /* host should surface the panel UI */ }
    func shouldHidePanel() { /* host should hide it */ }
    func trackAction(analytics: [String: String]) { /* forward to your analytics */ }
    func trackImpression(analytics: [String: String]) { /* forward to your analytics */ }
    func onKeyMomentSelected(contentId: String) { /* play the clip */ }
}

Features

Stats panel (MMA/UFC)

Fetches live fight data from the Helios supergraph, polls every 10s, retries with backoff.

let stats = instance.createStatsPresenter()
stats.start()

Task {
    for await state in stats.state {
        switch onEnum(of: state) {
        case .loading:
            print("Loading fights…")
        case .error(let e):
            print("Error: \(e.message)")
        case .success(let s):
            let event = s.event
            print("\(event.name) at \(event.venue)")
            for fight in event.fights {
                print("  \(fight.redFighter.lastName) vs \(fight.blueFighter.lastName)")
            }
        }
    }
}

stats.destroy()

Key Plays panel (Key Moments)

Host app pushes key-moment data into the SDK; the presenter handles sort order + playback progress.

let keyPlays = instance.createKeyPlaysPresenter()
keyPlays.start()

// Push moments from your backend.
instance.updateKeyMomentsData(data: [
    ParamountKeyMoment(contentId: "clip-1", title: "Round 1 KO", ...)
])

// Update playback progress as the user watches.
instance.updateKeyMomentsProgress(contentId: "clip-1", progress: 0.42)

// Change sort order.
instance.setKeyMomentsSortOrder(sortOrder: KeyMomentsSortOrder.newestFirst)

Task {
    for await state in keyPlays.state {
        print("\(state.moments.count) moments, active=\(state.activeContentId ?? "none")")
    }
}

keyPlays.destroy()

Animated Overlays

Rive-based broadcast overlays driven by the SDK's overlay queue.

let overlays = instance.createOverlayPresenter()
overlays.start()

Task {
    for await event in overlays.events {
        // event carries the Rive file URL + duration.
    }
}

overlays.destroy()

Type mapping

Kotlin Swift
StateFlow<T> AsyncSequence — consume with for await
sealed interface / sealed class Use switch onEnum(of:) for exhaustive matching
data object Foo FooType.shared singleton
List<T> Array<T>
Long Int64

Sealed state pattern

switch onEnum(of: state) {
case .loading:
    ProgressView()
case .error(let e):
    Text(e.message)
case .success(let s):
    ContentView(event: s.event)
}

Working example

A complete SwiftUI demo lives in demos/demo-tvos-paramount/ in this repo. It wires up Stats, Key Plays, Overlays, and the panel-visibility bridge.

License

Copyright (c) LessThan3


Installation

.binaryTarget(
    name: "paramountKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/paramountKit-4.0.8.145/paramountKit-4.0.8.145.zip",
    checksum: "9b8a92ad1fbf1f56e77d9ec4efd1de061979fa7c129ff3d3c4614a9c7ec95ed9"
)

foxKit 4.0.9.147

23 Apr 12:47
a91c41c

Choose a tag to compare

Installation

.binaryTarget(
    name: "foxKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/foxKit-4.0.9.147/foxKit-4.0.9.147.zip",
    checksum: "729bac4131ac23a15138328967fd231dcdd286ff7dab12cfe38e7f5b7807bbb5"
)

foxKit 4.0.8.146

22 Apr 18:44
fc6946b

Choose a tag to compare

Installation

.binaryTarget(
    name: "foxKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/foxKit-4.0.8.146/foxKit-4.0.8.146.zip",
    checksum: "753c7b62b42a00e98e848bdeef12319a017629b1a09a255e9910e3bf40c09b86"
)

foxKit 4.0.8.145

22 Apr 17:48
be20d11

Choose a tag to compare

Installation

.binaryTarget(
    name: "foxKit",
    url: "https://github.com/lessthan3/MaestroKit.android/releases/download/foxKit-4.0.8.145/foxKit-4.0.8.145.zip",
    checksum: "14927bad9c9cc253a4829ed491bd72b07dd8285691a24ff06b752b38b68c050d"
)