Catalyst: ohne Netz, ohne Übersetzung, ohne Fenstergröße

Drei Fehler auf einmal, und alle drei meine.

**Die App kam gar nicht ins Netz.** Ein Catalyst-Programm läuft in der Sandbox
und braucht eine ausdrückliche Erlaubnis für ausgehende Verbindungen. Ohne sie
gibt es keine Fehlermeldung — der Ladekreis dreht sich einfach für immer, und
genau so sah es aus.

**In der Seitenleiste standen Schlüssel statt Wörtern** — „sidebar.downloads"
statt „Downloads". Ich hatte zwei Fassungen derselben Beschriftung gebaut, eine
mit `LocalizedStringKey` und eine mit `String` für Titel, die vom Server
kommen. Bei einem Literal darf Swift sich für beide entscheiden, und es
entschied sich nicht überall gleich. Jetzt gibt es eine Fassung; wer einen
fertigen Text hat, baut sein `Text` selbst.

**Das Fenster öffnete wieder in Notizzettelgröße.** Meine Größenangabe hing an
`os(macOS)` — unter Catalyst gilt aber `os(iOS)`, also griff sie nicht. Dort
hängt die Größe ohnehin an der Szene, nicht am Fenster.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-13 16:22:42 +02:00
co-authored by Claude Opus 5
parent f296d7ae1a
commit 39d9138911
6 changed files with 3777 additions and 3730 deletions
+13
View File
@@ -0,0 +1,13 @@
<?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>
+31 -1
View File
@@ -70,9 +70,18 @@ struct FlixyApp: App {
// Eine Untergrenze, unter der die Oberfläche nicht mehr // Eine Untergrenze, unter der die Oberfläche nicht mehr
// 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.
#if os(macOS) //
// `os(macOS)` allein reichte nicht — unter Catalyst gilt
// `os(iOS)`, und genau deshalb öffnete das Fenster wieder in
// Notizzettelgröße.
#if os(macOS) || targetEnvironment(macCatalyst)
.frame(minWidth: 900, minHeight: 620) .frame(minWidth: 900, minHeight: 620)
#endif #endif
#if targetEnvironment(macCatalyst)
// Unter Catalyst gibt es `defaultSize` nicht; die Größe hängt
// an der Szene.
.task { Self.widenWindow() }
#endif
.environment(session) .environment(session)
.environment(playback) .environment(playback)
.environment(playbackSettings) .environment(playbackSettings)
@@ -123,6 +132,27 @@ struct FlixyApp: App {
} }
#if os(iOS) #if os(iOS)
#if targetEnvironment(macCatalyst)
extension FlixyApp {
/// Gibt dem Fenster eine vernünftige Mindestgröße.
///
/// Unter Catalyst öffnet macOS sonst ein Fenster von der Größe eines
/// Notizzettels — und darin fällt der Aufmacher in sich zusammen, weil
/// seine Abstände dehnbar sind.
@MainActor
static func widenWindow() {
for scene in UIApplication.shared.connectedScenes {
guard let windowScene = scene as? UIWindowScene else { continue }
windowScene.sizeRestrictions?.minimumSize = CGSize(width: 900, height: 620)
windowScene.sizeRestrictions?.maximumSize = CGSize(
width: CGFloat.greatestFiniteMagnitude,
height: CGFloat.greatestFiniteMagnitude
)
}
}
}
#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
final class AppDelegate: NSObject, UIApplicationDelegate { final class AppDelegate: NSObject, UIApplicationDelegate {
+2
View File
@@ -40,6 +40,8 @@
<key>NSAllowsLocalNetworking</key> <key>NSAllowsLocalNetworking</key>
<true/> <true/>
</dict> </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> <key>UIBackgroundModes</key>
<array> <array>
<string>audio</string> <string>audio</string>
File diff suppressed because it is too large Load Diff
+11 -14
View File
@@ -191,7 +191,7 @@ struct RootView: View {
) { ) {
mediaStack { LibraryView(library: library) } mediaStack { LibraryView(library: library) }
} label: { } label: {
tabLabel(library.title, symbol: symbol(for: library.kind)) sidebarLabel(Text(library.title), symbol: symbol(for: library.kind))
} }
.customizationID("flixy.tab.library.\(library.id)") .customizationID("flixy.tab.library.\(library.id)")
} }
@@ -292,22 +292,19 @@ struct RootView: View {
#endif #endif
/// Die Beschriftung eines Eintrags. /// Die Beschriftung eines Eintrags.
///
/// **Ein** Aufruf, nicht zwei. Es gab hier eine zweite Fassung für Titel,
/// die vom Server kommen — mit `String` statt `LocalizedStringKey`. Swift
/// darf sich bei einem Literal für beide entscheiden, und es entschied sich
/// nicht überall gleich: in der Seitenleiste stand plötzlich
/// „sidebar.downloads" statt „Downloads". Wer einen fertigen Text hat,
/// baut sein `Text` jetzt selbst.
private func tabLabel(_ title: LocalizedStringKey, symbol: String) -> some View { private func tabLabel(_ title: LocalizedStringKey, symbol: String) -> some View {
let label = Label(title, systemImage: symbol) sidebarLabel(Text(title), symbol: symbol)
#if os(macOS)
return label.frame(
minWidth: Self.sidebarWidth.min - 40,
maxWidth: Self.sidebarWidth.max - 40,
alignment: .leading
)
#else
return label
#endif
} }
/// Dieselbe Beschriftung, wenn der Titel erst vom Server kommt. private func sidebarLabel(_ title: Text, symbol: String) -> some View {
private func tabLabel(_ title: String, symbol: String) -> some View { let label = Label { title } icon: { Image(systemName: symbol) }
let label = Label(title, systemImage: symbol)
#if os(macOS) #if os(macOS)
return label.frame( return label.frame(
minWidth: Self.sidebarWidth.min - 40, minWidth: Self.sidebarWidth.min - 40,
+4
View File
@@ -201,6 +201,7 @@ targets:
CODE_SIGN_IDENTITY: "-" CODE_SIGN_IDENTITY: "-"
DEVELOPMENT_TEAM: "" DEVELOPMENT_TEAM: ""
ENABLE_HARDENED_RUNTIME: NO ENABLE_HARDENED_RUNTIME: NO
CODE_SIGN_ENTITLEMENTS: Flixy/Flixy-macCatalyst.entitlements
info: info:
path: Flixy/Info-macOS.plist path: Flixy/Info-macOS.plist
properties: properties:
@@ -222,6 +223,9 @@ targets:
ITSAppUsesNonExemptEncryption: false ITSAppUsesNonExemptEncryption: false
NSAppTransportSecurity: NSAppTransportSecurity:
NSAllowsLocalNetworking: true NSAllowsLocalNetworking: true
NSLocalNetworkUsageDescription: >-
Flixy benötigt Zugriff auf das lokale Netzwerk, um deinen
Medienserver zu finden und Filme direkt von ihm zu laden.
DownloadWidget: DownloadWidget:
type: app-extension type: app-extension