FlixyMac ist weg

VLCKit liefert Teile für iOS, macOS, tvOS und die Simulatoren — aber
keinen für Catalyst. Deshalb hing `FlixyVLC` gar nicht erst am Mac-Ziel,
und deshalb musste dort jedes MKV und jeder DTS-Ton vom Server
umgerechnet werden. Bei einem Medienclient ist das nicht ein Detail am
Rand, sondern der Zweck der Übung.

„Für iPad angepasst" ist derselbe iOS-Bau und lädt denselben iOS-Teil von
VLCKit. Damit läuft auf dem Mac, was auf dem iPad läuft.

Was Catalyst dafür konnte — eine `.app` zum Weitergeben, Intel-Macs, die
Fensterleiste über AppKit — wiegt hier nichts auf: ein Nutzer, ein
Apple-Silicon-Mac.

Die Fenstergröße hing an `#if targetEnvironment(macCatalyst)` und fragt
jetzt `FlixyPlatform.isMac`. `sizeRestrictions` ist auf dem iPhone `nil`,
das Fragezeichen ist die ganze Fallunterscheidung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-15 21:00:44 +02:00
co-authored by Claude Opus 5
parent f3ea1ea891
commit 5dd2daf3ed
4 changed files with 21 additions and 198 deletions
-13
View File
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Catalyst-Programme laufen in der Sandbox. Ohne die Erlaubnis für
ausgehende Verbindungen erreicht die App keinen Server — und zwar
ohne Fehlermeldung: der Ladekreis dreht sich einfach für immer. -->
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
+17 -13
View File
@@ -71,17 +71,18 @@ struct FlixyApp: App {
// aufgeht: schmaler als das hier klappt die Seitenleiste zu // aufgeht: schmaler als das hier klappt die Seitenleiste zu
// und die Reihen zeigen anderthalb Kacheln. // und die Reihen zeigen anderthalb Kacheln.
// //
// `os(macOS)` allein reichte nicht — unter Catalyst gilt // Zur Laufzeit gefragt, nicht beim Übersetzen: auf dem Mac
// `os(iOS)`, und genau deshalb öffnete das Fenster wieder in // läuft genau dieser iOS-Bau, und `os(macOS)` ist dabei
// Notizzettelgröße. // falsch. Ohne Untergrenze öffnet das Fenster in
#if os(macOS) || targetEnvironment(macCatalyst) // Notizzettelgröße, und darin fällt der Aufmacher in sich
.frame(minWidth: 900, minHeight: 620) // zusammen, weil seine Abstände dehnbar sind.
#endif .frame(
#if targetEnvironment(macCatalyst) minWidth: FlixyPlatform.isMac ? 900 : nil,
// Unter Catalyst gibt es `defaultSize` nicht; die Größe hängt minHeight: FlixyPlatform.isMac ? 620 : nil
// an der Szene. )
// `defaultSize` gibt es hier nicht; die Größe hängt an der
// Szene.
.task { Self.widenWindow() } .task { Self.widenWindow() }
#endif
.environment(session) .environment(session)
.environment(playback) .environment(playback)
.environment(playbackSettings) .environment(playbackSettings)
@@ -132,13 +133,17 @@ struct FlixyApp: App {
} }
#if os(iOS) #if os(iOS)
#if targetEnvironment(macCatalyst)
extension FlixyApp { extension FlixyApp {
/// Gibt dem Fenster eine vernünftige Mindestgröße. /// Gibt dem Fenster eine vernünftige Mindestgröße.
/// ///
/// Unter Catalyst öffnet macOS sonst ein Fenster von der Größe eines /// Auf dem Mac öffnet das System sonst ein Fenster von der Größe eines
/// Notizzettels — und darin fällt der Aufmacher in sich zusammen, weil /// Notizzettels — und darin fällt der Aufmacher in sich zusammen, weil
/// seine Abstände dehnbar sind. /// seine Abstände dehnbar sind.
///
/// `sizeRestrictions` gibt es nur dort, wo Fenster sich überhaupt frei
/// ziehen lassen; auf dem iPhone ist die Eigenschaft `nil`. Das
/// Fragezeichen ist deshalb die ganze Fallunterscheidung — ein Aufruf
/// auf einem Gerät ohne Fenster tut schlicht nichts.
@MainActor @MainActor
static func widenWindow() { static func widenWindow() {
for scene in UIApplication.shared.connectedScenes { for scene in UIApplication.shared.connectedScenes {
@@ -151,7 +156,6 @@ extension FlixyApp {
} }
} }
} }
#endif
/// Der klassische App-Delegat, für das eine, was SwiftUI nicht abdeckt. /// Der klassische App-Delegat, für das eine, was SwiftUI nicht abdeckt.
@MainActor @MainActor
-63
View File
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Flixy</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.scarriffleservices.flixy.auth</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.scarriffleservices.flixy</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.entertainment</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
<key>NSLocalNetworkUsageDescription</key>
<string>Flixy benötigt Zugriff auf das lokale Netzwerk, um deinen Medienserver zu finden und Filme direkt von ihm zu laden.</string>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
<key>UILaunchScreen</key>
<dict>
<key>UIColorName</key>
<string>LaunchBackground</string>
</dict>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIUserInterfaceStyle</key>
<string>Dark</string>
</dict>
</plist>
+4 -109
View File
@@ -44,17 +44,9 @@ targets:
# einzeln ein — dann fehlt das Icon, ohne dass irgendwo ein Fehler # einzeln ein — dann fehlt das Icon, ohne dass irgendwo ein Fehler
# auftaucht. # auftaucht.
# #
# Die Info.plist des jeweils anderen Ziels muss ebenfalls hinaus.
# XcodeGen nimmt nur die eigene automatisch heraus; die fremde landet
# als gewöhnliche Ressource unverarbeitet im Bündel — mitsamt dem
# wörtlichen $(PRODUCT_BUNDLE_IDENTIFIER). Beim Installieren liest das
# Gerät dann diese statt der richtigen und lehnt die App als „not a
# valid bundle" ab.
- path: Flixy - path: Flixy
excludes: excludes:
- "AppIcon.icon" - "AppIcon.icon"
- "Info-macOS.plist"
- "Flixy-macCatalyst.entitlements"
- path: Flixy/AppIcon.icon - path: Flixy/AppIcon.icon
type: file type: file
dependencies: dependencies:
@@ -163,107 +155,6 @@ targets:
Flixy benötigt Zugriff auf das lokale Netzwerk, um deinen Flixy benötigt Zugriff auf das lokale Netzwerk, um deinen
Plex-Server zu finden und Medien direkt von ihm zu laden. Plex-Server zu finden und Medien direkt von ihm zu laden.
# 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.
#
# Mac Catalyst statt einer eigenen Mac-App: die iPad-Oberfläche läuft damit
# unverändert auf dem Mac — gleiche Schriftgrößen, gleiche Seitenleiste,
# gleiche Abstände. Eine native Mac-App war der erste Versuch; sie sah an
# zwei Dutzend Stellen anders aus, weil AppKit dieselben Dinge anders misst,
# und jede davon hätte einzeln nachgezogen werden müssen.
#
# Ohne DownloadWidget (Live Activities gibt es hier nicht) und **ohne
# FlixyVLC**: dessen Binärpaket hat keinen Teil für Catalyst. MKV und DTS
# werden dort deshalb vom Server umgerechnet statt unverändert übertragen —
# siehe `PlaybackSettings.hasFallbackEngine`.
FlixyMac:
type: application
platform: iOS
scheme: {}
sources:
# Siehe Flixy: umgekehrt genauso, sonst trägt das Mac-Bündel die
# Info.plist des iPhones in seinen Ressourcen.
- path: Flixy
excludes:
- "AppIcon.icon"
- "Info.plist"
- path: Flixy/AppIcon.icon
type: file
dependencies:
- package: FlixyKit
product: MediaKit
- package: FlixyKit
product: PlexKit
- package: FlixyKit
product: JellyfinKit
- package: FlixyKit
product: FlixyDesign
- package: FlixyKit
product: FlixyPlayback
- package: FlixyKit
product: FlixyDownloads
settings:
base:
SUPPORTS_MACCATALYST: YES
# Nur Mac: dieses Ziel ist nicht dazu da, aufs iPhone zu wandern.
SUPPORTED_PLATFORMS: macosx
# „An das iPad angeglichen" statt „für den Mac optimiert" — genau
# darum geht es.
MACCATALYST_OPTIMIZE_FOR_MAC: NO
# **Eine eigene Kennung, nicht dieselbe wie die iPhone-App.**
#
# Hier stand `DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER: NO`, und
# damit trugen beide Programme `com.scarriffleservices.flixy`. Auf
# einem Rechner, auf dem die iPad-Fassung installiert ist — und auf
# einem Apple-Silicon-Mac ist sie das leicht — gibt es die Kennung
# dann zweimal. Das System entscheidet sich für **eines** davon, und
# nicht unbedingt für das eben gebaute: der Start sieht aus, als
# geschähe nichts.
#
# Voreingestellt ist bei Apple `YES`, und zwar genau deshalb. Daraus
# wird `maccatalyst.com.scarriffleservices.flixy`.
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER: YES
PRODUCT_BUNDLE_IDENTIFIER: com.scarriffleservices.flixy
PRODUCT_NAME: Flixy
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
TARGETED_DEVICE_FAMILY: "2"
# Richtig signiert, wie die iPhone-App auch.
#
# Vorher war es eine Ad-hoc-Signatur ohne Team, damit ein Bau zum
# Ansehen nicht nach dem Schlüsselbund fragt. Nur legt Flixy den
# Server-Token im Schlüsselbund ab, und einem Sandbox-Programm ohne
# `application-identifier` verweigert der das — die Anmeldung hielte
# keinen Neustart aus.
CODE_SIGN_STYLE: Automatic
ENABLE_HARDENED_RUNTIME: NO
CODE_SIGN_ENTITLEMENTS: Flixy/Flixy-macCatalyst.entitlements
info:
path: Flixy/Info-macOS.plist
properties:
CFBundleDisplayName: Flixy
UILaunchScreen:
UIColorName: LaunchBackground
UIUserInterfaceStyle: Dark
UISupportedInterfaceOrientations:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
UIBackgroundModes:
- audio
LSApplicationCategoryType: public.app-category.entertainment
CFBundleURLTypes:
- CFBundleURLName: com.scarriffleservices.flixy.auth
CFBundleURLSchemes:
- com.scarriffleservices.flixy
ITSAppUsesNonExemptEncryption: false
NSAppTransportSecurity:
NSAllowsLocalNetworking: true
NSLocalNetworkUsageDescription: >-
Flixy benötigt Zugriff auf das lokale Netzwerk, um deinen
Medienserver zu finden und Filme direkt von ihm zu laden.
# Nur zum Hinsehen: fährt die App mit der Attrappe in einen bestimmten # 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. # Zustand und hält sie dort an, damit von außen fotografiert werden kann.
# Kein Teil der App, wird nie mitgeliefert. # Kein Teil der App, wird nie mitgeliefert.
@@ -282,6 +173,10 @@ targets:
CODE_SIGN_STYLE: Automatic CODE_SIGN_STYLE: Automatic
GENERATE_INFOPLIST_FILE: YES 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: DownloadWidget:
type: app-extension type: app-extension
platform: iOS platform: iOS