Files
Flaro/project.yml
T
ScarriffleandClaude Opus 5 6326c8c24c Ein Apple-TV-Target, und es zeigt schon etwas
Das leere Gerüst: eigene Wurzel FlixyTVApp, eigenes Target FlixyTV in
project.yml, eigener Asset-Katalog. Es beweist Target, Icon, Signierung
und Paketauflösung auf einen Schlag — bevor eine Zeile Logik daran hängt.

**Das Icon von Hand gebaut.** Icon Composer deckt iOS, macOS und watchOS
ab, tvOS nicht: der Fernseher verlangt gestapelte Bilder, damit die
Parallaxe beim Wischen etwas zu bewegen hat. Zwei Ebenen aus derselben
Marke — Verlauf hinten, Dreieck vorn —, dazu App-Store-Icon und beide
Top-Shelf-Bilder. Ohne das breite lehnt App Store Connect den Upload mit
90513 ab.

**Zwei Annahmen aus dem Plan haben sich beim Bauen erledigt.**
PlexWebAuthenticator übersetzt nicht: ASWebAuthenticationSession steht
zwar im tvOS-SDK, aber presentationContextProvider, cancel() und der
Rest sind dort nicht verfügbar. Der Typ bleibt trotzdem stehen — als
Attrappe, die sofort „ging nicht" meldet. Ihn herauszuschneiden hiesse,
die Zustandsmaschine der Anmeldung für eine Plattform zu spalten, die
diesen Zweig nie betritt. Dieselbe Bauform wie bei OrientationLock.
NowPlaying wartet auf den Player in Schritt sieben.

**Und eine Messung statt einer Vermutung.** Der Plan führte zwei offene
Annahmen über den Sicherheitsrand. Der Simulator beantwortet beide:
SwiftUI legt ihn von selbst an, und er misst sechzig oben und unten,
achtzig seitlich — nicht neunzig. Nutzfläche 1760×960.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-29 17:18:03 +02:00

288 lines
11 KiB
YAML

name: Flixy
options:
bundleIdPrefix: com.scarriffleservices
deploymentTarget:
iOS: "26.0"
macOS: "26.0"
tvOS: "26.0"
createIntermediateGroups: true
groupSortPosition: top
developmentLanguage: en
settings:
base:
DEVELOPMENT_TEAM: PP34X97WS3
SWIFT_VERSION: "6.0"
MARKETING_VERSION: "0.1.0"
CURRENT_PROJECT_VERSION: "1"
SWIFT_STRICT_CONCURRENCY: complete
packages:
FlixyKit:
path: Packages/FlixyKit
# Eigenes Package, weil das VLCKit-Binärpaket 920 MB wiegt und sonst bei
# jedem `swift test` in FlixyKit mitgezogen würde.
FlixyVLC:
path: Packages/FlixyVLC
targets:
Flixy:
type: application
platform: iOS
# Ausdrücklich aufgeschrieben, statt Xcode raten zu lassen.
#
# Xcode legt für jedes Ziel von selbst ein Schema an — aber im
# Benutzerordner, und `xcodegen generate` räumt den mit weg. Danach
# findet `xcodebuild` kein Schema mehr und kann die Pakete nicht
# auflösen. Hier steht es im Projekt und überlebt jedes Neuerzeugen.
scheme:
testTargets:
- FlixyUITests
sources:
# Das Icon ist ein Bündel, also technisch ein Ordner. Ohne diesen
# Ausschluss läuft XcodeGen hinein und trägt icon.json und play.svg
# einzeln ein — dann fehlt das Icon, ohne dass irgendwo ein Fehler
# auftaucht.
#
- path: Flixy
excludes:
- "AppIcon.icon"
- path: Flixy/AppIcon.icon
type: file
dependencies:
- target: DownloadWidget
# Die neutrale Grundschicht. Ausdrücklich genannt, obwohl sie über
# PlexKit ohnehin im Baum hängt: die App soll sie direkt benutzen und
# nicht davon abhängen, dass ein bestimmter Server sie mitschleppt.
- package: FlixyKit
product: MediaKit
- package: FlixyKit
product: PlexKit
# Der zweite Server. Steht neben PlexKit, nicht darin: die beiden teilen
# die neutrale Schicht und sonst nichts.
- package: FlixyKit
product: JellyfinKit
- package: FlixyKit
product: FlixyDesign
- package: FlixyKit
product: FlixyPlayback
- package: FlixyKit
product: FlixyDownloads
- package: FlixyVLC
product: FlixyVLC
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.flixy
PRODUCT_NAME: Flixy
# Verweist auf AppIcon.icon. Der frühere leere AppIcon.appiconset im
# Asset-Katalog ist entfernt — zwei Dinge namens AppIcon, und Xcode
# nimmt das falsche.
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
# iPhone und iPad aus demselben Target.
TARGETED_DEVICE_FAMILY: "1,2"
CODE_SIGN_STYLE: Automatic
info:
path: Flixy/Info.plist
properties:
CFBundleDisplayName: Flixy
UILaunchScreen:
UIColorName: LaunchBackground
# Der harte Schalter für „nur dunkel". Eine Ansicht mit
# .preferredColorScheme(.dark) allein reicht nicht: Systemdialoge,
# Statusleiste und Tastatur richten sich danach nicht.
UIUserInterfaceStyle: Dark
# Alle drei bleiben eingetragen: die Info.plist sagt, was die App
# grundsätzlich kann. Was davon gerade gilt, entscheidet zur Laufzeit
# OrientationLock über den App-Delegaten — Hochformat beim Blättern,
# Querformat im Player.
UISupportedInterfaceOrientations:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
# Ohne diesen Modus hält iOS die Wiedergabe an, sobald die App in den
# Hintergrund geht — und Bild-in-Bild gäbe es gar nicht.
UIBackgroundModes:
- audio
# Das Schema, über das Plex nach der Anmeldung zurückschickt. Ohne
# diesen Eintrag kennt iOS es nicht, und ASWebAuthenticationSession
# käme nie zurück — das Anmeldefenster bliebe offen stehen.
CFBundleURLTypes:
- CFBundleURLName: com.scarriffleservices.flixy.auth
CFBundleURLSchemes:
- com.scarriffleservices.flixy
# Die Ausfuhr-Erklärung zur Verschlüsselung.
#
# `false` heißt: die App nutzt ausschließlich Verschlüsselung, die
# unter die Ausnahmeregelung fällt. Das trifft hier zu — HTTPS über
# URLSession und der Schlüsselbund für die Tokens, beides vom
# Betriebssystem gestellt. Eigene Algorithmen gibt es keine.
#
# Ohne diesen Eintrag fragt App Store Connect bei JEDEM Build erneut
# („Missing Compliance"), und der Build lässt sich bis dahin nicht
# verteilen.
#
# Zu beachten, falls sich das ändert: VLCKit ist ein fremdes Binary
# und bringt eigene Netzwerkbibliotheken mit. Solange nur Dateien vom
# eigenen Server abgespielt werden, bleibt es bei Standardverfahren.
# Käme irgendwann etwas mit eigener Verschlüsselung dazu — DRM etwa —,
# gehört dieser Wert überprüft.
ITSAppUsesNonExemptEncryption: false
# Ohne diesen Schlüssel lehnt ActivityKit jede Anfrage ab — und
# zwar wortlos, was die Suche nach dem Grund unangenehm macht.
NSSupportsLiveActivities: true
NSAppTransportSecurity:
# Plex-Server im Heimnetz laufen überwiegend auf blankem HTTP an
# Port 32400. Diese Ausnahme erlaubt genau das, ohne die
# Transportsicherheit für das offene Netz abzuschalten.
NSAllowsLocalNetworking: true
# Seit iOS 14 verlangt jeder Zugriff auf Adressen im eigenen Netz eine
# Freigabe. Fehlt der Text, verweigert das System sie kommentarlos und
# die Serversuche findet dauerhaft nichts.
NSLocalNetworkUsageDescription: >-
Flixy benötigt Zugriff auf das lokale Netzwerk, um deinen
Plex-Server zu finden und Medien direkt von ihm zu laden.
# Die Fassung für den Fernseher.
#
# **Eigene Ansichten, geteilte Modelle.** Die Quellenpfade sind die ganze
# Aussage dieses Blocks: `FlixyTV/` gehört nur hierher, `Flixy/Session/`
# gehört beiden. Keine Datei muss dafür umziehen — XcodeGen nimmt Pfade je
# Ziel, und die iOS-Fassung sieht von der ganzen Sache nichts.
FlixyTV:
type: application
platform: tvOS
# Aus demselben Grund ausgeschrieben wie bei Flixy — siehe dort.
scheme: {}
sources:
# Die eigenen Ansichten.
- path: FlixyTV
# Die Modelle.
- path: Flixy/Session
excludes:
# Ein Fernseher dreht sich nicht.
- "OrientationLock.swift"
# Downloads gibt es hier nicht.
- "DownloadService.swift"
- "DownloadRefiller.swift"
# Kommt mit dem Player in Schritt sieben. Solange es ihn nicht gibt,
# hätte die Anmeldung beim System nichts anzumelden.
- "NowPlaying.swift"
# Reines Modell trotz des Ordnernamens: LoadState, ErrorText und
# MediaRoute liegen zusammen in einer Datei.
- path: Flixy/Views/LoadState.swift
type: file
- path: Flixy/Branding.swift
type: file
# Die Texte. Dieselben Schlüssel, dieselben Übersetzungen.
- path: Flixy/Resources/Localizable.xcstrings
type: file
dependencies:
- package: FlixyKit
product: MediaKit
# Mitgenommen, obwohl Plex in Fassung 1 nicht angeboten wird:
# FlixySession kennt PlexResource und PlexBackend in seiner
# Zustandsmaschine. Das Paket mitzunehmen ist billiger, als die Sitzung
# zu spalten — PlexClientIdentity benutzt nur UIDevice, und das gibt es
# auf tvOS.
- package: FlixyKit
product: PlexKit
- package: FlixyKit
product: JellyfinKit
- package: FlixyKit
product: FlixyDesign
- package: FlixyKit
product: FlixyPlayback
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.flixy.tv
PRODUCT_NAME: Flixy
# Nur Apple TV.
TARGETED_DEVICE_FAMILY: "3"
# Kein AppIcon.icon: Icon Composer deckt iOS, macOS und watchOS ab,
# tvOS nicht. Der Name zeigt auf die Brand-Assets-Gruppe im Katalog,
# und der Katalog liegt unter FlixyTV/Resources.
ASSETCATALOG_COMPILER_APPICON_NAME: "App Icon & Top Shelf Image"
CODE_SIGN_STYLE: Automatic
info:
path: FlixyTV/Info.plist
properties:
CFBundleDisplayName: Flixy
UIUserInterfaceStyle: Dark
ITSAppUsesNonExemptEncryption: false
# Was hier **nicht** steht, und warum:
#
# UILaunchScreen — tvOS hat kein Startbild dieser Art.
# UISupportedInterfaceOrientations — ein Fernseher dreht sich nicht.
# NSSupportsLiveActivities — ActivityKit fehlt im tvOS-SDK.
# CFBundleURLTypes — das Schema ist für die Plex-Rückkehr.
# UIBackgroundModes: audio — ein Apple TV schickt keine App in den
# Hintergrund, aus dem sie weiterspielen müsste.
NSAppTransportSecurity:
NSAllowsLocalNetworking: true
NSLocalNetworkUsageDescription: >-
Flixy benötigt Zugriff auf das lokale Netzwerk, um deinen
Jellyfin-Server zu erreichen.
# Nur zum Hinsehen: fährt die App mit der Attrappe in einen bestimmten
# Zustand und hält sie dort an, damit von außen fotografiert werden kann.
# Kein Teil der App, wird nie mitgeliefert.
FlixyUITests:
type: bundle.ui-testing
platform: iOS
sources:
- FlixyUITests
dependencies:
- target: Flixy
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.flixy.uitests
TEST_TARGET_NAME: Flixy
TARGETED_DEVICE_FAMILY: "1,2"
CODE_SIGN_STYLE: Automatic
GENERATE_INFOPLIST_FILE: YES
# Die Live Activity für Downloads. Eine eigene Erweiterung, weil iOS die
# Darstellung im Sperrbildschirm in einem getrennten Prozess zeichnet — die
# App selbst läuft zu dem Zeitpunkt meist gar nicht.
# Dieselben Quellen, dasselbe Aussehen.
DownloadWidget:
type: app-extension
platform: iOS
sources:
- path: DownloadWidget
dependencies:
- package: FlixyKit
product: FlixyDownloads
- package: FlixyKit
product: FlixyDesign
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.flixy.downloadwidget
PRODUCT_NAME: DownloadWidget
CODE_SIGN_STYLE: Automatic
SKIP_INSTALL: YES
# Von XcodeGen erzeugt statt von Hand geschrieben. Eine eigene Datei ohne
# CFBundleIdentifier führt zu einer Erweiterung ganz ohne Kennung — und
# der Fehler lautet dann „not prefixed with the parent app's bundle
# identifier", was auf eine falsche Fährte führt.
info:
path: DownloadWidget/Info.plist
properties:
CFBundleDisplayName: Flixy Downloads
NSExtension:
NSExtensionPointIdentifier: com.apple.widgetkit-extension