The built app reports CFBundleShortVersionString 0.0.1 (MARKETING_VERSION),
but metadata hardcoded 1.0, so SideStore rejected the version mismatch.
Now read the version from the built app's Info.plist so it always matches.
Debug config produces com.voidlink.tf.debug10.iOS, which mismatches the
com.voidlink.tf.iOS declared in VoidLink.json, so SideStore rejects the
install. Release produces the matching com.voidlink.tf.iOS.
Builds VoidLink via xcodebuild (no signing) on the macOS runner, packages
the .app into an .ipa, and uploads .ipa + metadata + icon to perlis so it
can be installed from the SideStore source at apps.bueso.eu.
The renderer setting previously forced an app quit (exit(0)) because
switching backends between sessions crashed or leaked. Fix the
underlying lifecycle bugs and remove the restart requirement:
- FrameQueue: really release frames in clear(), clear on session
start/stop, and guard start/stop with an owner so a stale session's
async cleanup can't pause a new session's queue
- MetalView: weak delegate (breaks retain cycle leaking the whole Metal
stack), never start two render threads, bound the shutdown wait to
avoid deadlocking against the render thread's dispatch_sync to main
- MetalViewController: explicit idempotent shutdown called from stream
teardown (viewDidDisappear isn't guaranteed); snapshot the renderer
in render-thread callbacks to avoid use-after-free during shutdown
- MetalVideoRenderer: make the shared colorspace name thread-safe and
ARC-managed instead of a CFStringRef over-released in dealloc; guard
NULL format description extensions
- Connection: drop the static renderer reference in DrCleanup
- VideoDecoderRenderer: cache the application background state via
notifications instead of calling UIKit from the decode queue
(Main Thread Checker violation)
- Frame: don't CFRetain(NULL) when a format desc has no extensions
- StreamFrameViewController: fix _streamView cleanup ordering
- Settings: apply the backend change in place (with the Metal caveats
alert) and update localized tips; takes effect on next stream
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>