# Apple clients `VoiceCat.Mac` and `VoiceCat.iOS` are .NET 10 AppKit and UIKit clients over the shared managed core. The ReplayKit upload extension under `native/apple/broadcast` remains Swift because it runs under the extension memory limit and writes the versioned shared audio ring. Build on macOS with Xcode and the pinned .NET workloads: ```bash ./scripts/build-native.ps1 ./scripts/build-native-ios.sh dotnet restore clients/apple/VoiceCat.Apple.slnx dotnet build clients/apple/VoiceCat.Apple.slnx -c Debug --no-restore ``` Use `publish-macos.sh --dry-run` to validate an ad-hoc macOS bundle. For distribution, set `VOICECAT_CODESIGN_IDENTITY`; optional notarization uses `APPLE_ID`, `APPLE_TEAM_ID`, and `APPLE_APP_PASSWORD`. For a physical iOS device, use `build-ios-device.sh` and `deploy-ios-device.sh`. The host and ReplayKit extension require signing profiles with App Group `group.me.iamtalon.voicecat`. Hardware validation must cover VoiceOver, background and lock behavior, interruptions, route changes, Bluetooth, ReplayKit, and iOS 27 ScreenCaptureKit audio. The shared ring contract is documented in `docs/broadcast-ring-format.md`.