Files
onyx/Packages/OnyxKit/Package.swift
Guido Schmit 433cdcc3dd Phase 4: Medien-Widget mit dreistufiger Kaskade
Adapter für alles inklusive Browser, AppleScript für Spotify und Musik,
Medientasten als letzte Reserve. Die Reihenfolge ist keine Vorliebe, sondern
Absicherung: Apple hat die Now-Playing-Schnittstelle in macOS 15.4 schon
einmal zugemacht. Fällt der Adapter aus, verliert das Widget seine Anzeige —
aber nicht seine Funktion. Deshalb bleiben die Transporttasten auch dann
bedienbar, wenn gar keine Metadaten da sind.

Der Fortschritt zählt zwischen den Ereignissen selbst hoch. Spike B hatte
gezeigt, dass elapsedTime nicht laufend nachgeliefert wird: ein Scrubber, der
stur den letzten Wert anzeigt, steht still, während der Titel läuft. Gerechnet
wird aus asOf und playbackRate, begrenzt auf die Titellänge — sonst zeigt die
Anzeige nach dem Ende weiter steigende Zahlen.

Teilmeldungen (diff = true) ergänzen den Stand, statt ihn zu ersetzen. Eine
Meldung mit nur der Position würde sonst Titel, Interpret und Cover löschen.

In AnyDecodable wird Bool vor Double geprüft. Andernfalls wird "playing": true
zu 1 und die Wiedergabe gilt für immer als angehalten.

Play/Pause schaltet sofort um, statt auf das nächste Ereignis zu warten. Ein
Knopf, der eine halbe Sekunde später reagiert, fühlt sich kaputt an; das echte
Ereignis korrigiert den Stand ohnehin.

Der Adapter liegt als Quellcode unter Vendor/ (BSD-3, Stand in
ONYX-VERSION.txt) und wird beim Bauen kompiliert, statt als fertige Binary
eingecheckt zu werden. Er wird bewusst nicht gelinkt: geladen wird er von
/usr/bin/perl, im eigenen Prozess greift Apples Entitlement-Prüfung.

124 Tests grün.
2026-08-10 21:02:13 +02:00

51 lines
2.4 KiB
Swift

// swift-tools-version: 6.2
import PackageDescription
let package = Package(
name: "OnyxKit",
// Quellsprache ist Englisch, damit die Schlüssel im Code lesbar bleiben.
// Deutsch kommt als Übersetzung dazu; die Systemsprache entscheidet.
defaultLocalization: "en",
platforms: [.macOS(.v26)],
products: [
.library(name: "OnyxCore", targets: ["OnyxCore"]),
.library(name: "OnyxDesign", targets: ["OnyxDesign"]),
.library(name: "OnyxNotch", targets: ["OnyxNotch"]),
.library(name: "OnyxWidgetKit", targets: ["OnyxWidgetKit"]),
.library(name: "OnyxMenuBar", targets: ["OnyxMenuBar"]),
.library(name: "CalendarProvider", targets: ["CalendarProvider"]),
.library(name: "WeatherProvider", targets: ["WeatherProvider"]),
.library(name: "MediaProvider", targets: ["MediaProvider"]),
],
targets: [
// Der String-Katalog muss ausdrücklich als Ressource stehen sonst gibt
// es kein `Bundle.module`, und die Übersetzungen wären zur Laufzeit
// unauffindbar.
.target(name: "OnyxCore", resources: [.process("Localizable.xcstrings")]),
.testTarget(name: "OnyxCoreTests", dependencies: ["OnyxCore"]),
.target(name: "OnyxDesign"),
.target(name: "OnyxNotch", dependencies: ["OnyxDesign"]),
.testTarget(name: "OnyxNotchTests", dependencies: ["OnyxNotch"]),
.target(name: "OnyxWidgetKit", dependencies: ["OnyxDesign"]),
.testTarget(name: "OnyxWidgetKitTests", dependencies: ["OnyxWidgetKit"]),
.target(name: "OnyxMenuBar", dependencies: ["OnyxDesign", "OnyxWidgetKit"]),
.testTarget(name: "OnyxMenuBarTests", dependencies: ["OnyxMenuBar"]),
.target(name: "CalendarProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit"],
resources: [.process("Localizable.xcstrings")]),
.testTarget(name: "CalendarProviderTests", dependencies: ["CalendarProvider"]),
.target(name: "WeatherProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit"],
resources: [.process("Localizable.xcstrings")]),
.testTarget(name: "WeatherProviderTests", dependencies: ["WeatherProvider"]),
.target(name: "MediaProvider", dependencies: ["OnyxDesign", "OnyxWidgetKit"],
resources: [.process("Localizable.xcstrings")]),
.testTarget(name: "MediaProviderTests", dependencies: ["MediaProvider"]),
]
)