docs: audit Apple SDK and UI API choices

This commit is contained in:
2026-10-22 09:10:51 +02:00
parent 9a850e1722
commit f1893a5a5f
2 changed files with 20 additions and 2 deletions
+17
View File
@@ -19,6 +19,23 @@ With the macOS 27 SDK, the player uses a private `ViewState` alias for the `Swif
The resulting `.build/terebi.app` is self-contained: copy the whole app to a compatible Mac of the same architecture. No separate FFmpeg, Python, or yt-dlp installation is needed to run it.
### Apple SDK and UI API audit
Audited on 2026-10-22 with Xcode 27.0, macOS SDK 27.0 and Swift 6.4, in Swift 6 language mode. The build uses the active `xcrun` toolchain, not a pinned old SDK. `Makefile`, `Package.swift` and `Resources/Info.plist` consistently retain macOS 15 as the minimum; the rebuilt player and bootstrap report SDK 27.0 / minimum OS 15.0 in their Mach-O build metadata. A newer build SDK does not require raising the minimum OS; newer APIs still need availability guards.
**Keep the SwiftUI/AppKit architecture.** The app already uses SwiftUI `App`, `Window`, `Commands`, focus, typed URL drops, two-value `onChange` and `WindowDragGesture`. AppKit bridges serve specific native requirements, not a second legacy UI.
| Area | Assessment and decision |
| --- | --- |
| Native views and windows | Keep `NSViewRepresentable` bridges in `Sources/App/TerebiApp.swift` and `CompactWindowController`. They preserve the Metal renderer, buffered slider drawing, user tracking versus Cast feedback, native input routing and same-window compact/fullscreen geometry. [Apple documents this interoperability](https://developer.apple.com/documentation/swiftui/nsviewrepresentable). |
| State observation | `PlayerModel` and `CastDiscovery` use supported `ObservableObject`/`@Published`. [Observation](https://developer.apple.com/documentation/swiftui/migrating-from-the-observable-object-protocol-to-the-observable-macro) is available from macOS 14 and can narrow view invalidation. Consider it when profiling demonstrates unnecessary updates; no performance defect was measured here. A migration must preserve manual compact/Cast notifications, bindings and focused commands together. |
| Cast discovery | The clearest platform migration candidate is `NetServiceBrowser`/`NetService` in `Sources/App/CastSession.swift`. SDK 27's `Foundation/NSNetServices.h` recommends Network framework using **future-deprecation** annotations (`API_TO_BE_DEPRECATED`), not a reached removal date. Prefer [`NWBrowser`](https://developer.apple.com/documentation/network/nwbrowser) in a scoped migration that retains TXT identity/name records, device removal/deduplication, resolved endpoints and receiver-host routing for the media server. Current discovery still compiles without warnings. |
| App activation | `Sources/App/Bootstrap.swift` and `Sources/App/TerebiApp.swift` use `activate(ignoringOtherApps:)`. SDK 27's `AppKit/NSApplication.h` recommends [`activate()`](https://developer.apple.com/documentation/appkit/nsapplication/activate()), available from macOS 14, with a future-deprecation annotation. Migrate deliberately: the replacement does not guarantee foreground activation, so launch, focus and error-alert behavior need native verification. |
| Glass/chrome | `PlayerGlass` uses supported `NSVisualEffectView`, not native Liquid Glass. [`glassEffect`](https://developer.apple.com/documentation/swiftui/view/glasseffect(_:in:)) / [`NSGlassEffectView`](https://developer.apple.com/documentation/appkit/nsglasseffectview) require macOS 26; AppKit's `effectIsInteractive` requires 27. Optional adoption belongs on controls/chrome, not every content background, with the macOS 15 path retained and visual/accessibility verification. See [Apple's materials guidance](https://developer.apple.com/design/human-interface-guidelines/materials). |
| Playback backend | Keep MetalKit `MTKView` and the Core Audio output callback in `Sources/macOS/Output.mm`. They implement rendering and audio-clock synchronization; SwiftUI is not a replacement for that backend. |
Verification: forced recompilation of the Swift player, Objective-C++ renderer, bootstrap and CLI against the active SDK passed without compiler diagnostics; bundling/signature verification, CLI `--help`, and loading the rebuilt player dylib with its exported entry point passed. This was an API/toolchain audit, not a visual review, an exhaustive certification of every backend symbol, or a runtime test on macOS 15. No behavioral migrations were made.
### Install
```sh