Tell the DJ turns parties into shared playlists: guests scan a QR code to request songs, while hosts see requests ranked in real time and control what plays next. Available on iOS and Android, it is built from a shared Swift/SwiftUI codebase using SkipLite.
// swift-tools-version: 6.3
// This is a Skip (https://skip.tools) package,
// containing a Swift Package Manager project
// that will use the Skip build plugin to transpile the
// Swift Package, Sources, and Tests into an
// Android Gradle Project with Kotlin sources and JUnit tests.
import PackageDescription
let package = Package(
name: "tell-the-dj",
defaultLocalization: "en",
platforms: [.iOS(.v17), .macOS(.v14), .tvOS(.v16), .watchOS(.v9), .macCatalyst(.v16)],
products: [
.library(name: "TellTheDJApp", type: .dynamic, targets: ["TellTheDJ"]),
.library(name: "TellTheDJModel", targets: ["TellTheDJModel"]),
.library(name: "TellTheDJWidget", targets: ["TellTheDJWidget"]),
],
dependencies: [
.package(url: "https://source.skip.tools/skip.git", .upToNextMajor(from: .init(1, 9, 2))),
// Project-owned fork of skip-ui, pinned at upstream 1.59.0 (feature 049).
//
// Two reasons, both measured rather than assumed:
// 1. Upstream sheets ignore the soft keyboard on Android. `contentWindowInsets` is zeroed and
// `PresentationRoot`'s `imePadding()` is gated on an internal `_isEdgeToEdge`, so a
// `.medium` sheet keeps its content in the bottom half of the screen while the keyboard
// covers that half — the email sign-in field was unreachable. Nothing at app level fixes
// it: `presentationDetents(_:selection:)` is a no-op on Android, and padding the content
// only squeezes it inside a fixed-height sheet (verified on-device, then reverted).
// Patched in `Sources/SkipUI/SkipUI/Layout/Presentation.swift`.
// 2. 1.59.0 also fixes upstream the presentation scroll-axis / IntrinsicSize crash we had
// worked around locally (see `OptionEditorSheet`'s doc comment — it bit the value-row
// editors 4x).
//
// Fetched by URL, NOT by local path. A `.package(path: "../skip-ui")` builds only on the one
// machine that happens to have the fork checked out beside this repo — it is not reproducible
// on another checkout or in CI, and the failure is a resolve error rather than anything that
// points at the cause (feature 049 T102). The branch is pushed; `Package.resolved` pins the
// exact revision, so the branch reference does not make the build float.
//
// Revert to the upstream URL once the sheet/IME fix lands there.
.package(url: "https://github.com/BPHvZ/skip-ui.git", branch: "fix/sheet-ime-insets"),
.package(
url: "https://source.skip.tools/skip-foundation.git", .upToNextMajor(from: .init(1, 4, 1))),
.package(url: "https://source.skip.tools/skip-model.git", .upToNextMajor(from: .init(1, 7, 4))),
.package(
url: "https://github.com/DenDmitriev/DominantColors.git", .upToNextMajor(from: .init(1, 2, 2))
),
.package(
url: "https://github.com/google/GoogleSignIn-iOS.git", .upToNextMajor(from: .init(9, 1, 0))),
.package(
url: "https://github.com/twostraws/CodeScanner.git", .upToNextMajor(from: .init(2, 5, 2))),
.package(path: "../skip-firebase"),
.package(path: "../skip-spotify"),
.package(path: "../skip-rive"),
.package(path: "../skip-apple-music"),
.package(path: "../skip-lottie"),
.package(path: "../skip-shazam"),
.package(path: "../skip-iap"),
.package(path: "../skip-stripe"),
.package(path: "../skip-chromecast"),
.package(path: "../skip-admob"),
.package(path: "../skip-activity-aware"),
.package(path: "../skip-pdf"),
.package(path: "../skip-tidal"),
],
App name
Tell the DJ
Developer / publisher
Bart van Zeist
App Store URL
https://apps.apple.com/us/app/tell-the-dj/id1594097997
Play Store URL
https://play.google.com/store/apps/details?id=com.simpleappsfarm.tell_the_dj
One- or two-sentence description
Tell the DJ turns parties into shared playlists: guests scan a QR code to request songs, while hosts see requests ranked in real time and control what plays next. Available on iOS and Android, it is built from a shared Swift/SwiftUI codebase using SkipLite.
Skip mode
SkipLite (Swift transpiled to Kotlin)
Source repository (optional)
No response
Demonstration that the app is built with Skip
Snippet of my Package.swift
Developer website (optional)
https://simpleappsfarm.com
Confirmations