Files
voice-cat/clients/apple/dotnet/README.md
T
Talon d0a72176ba
.NET port / test (macos-latest) (push) Canceled after 0s
.NET port / test (ubuntu-24.04) (push) Canceled after 0s
.NET port / test (windows-latest) (push) Canceled after 0s
.NET port / apple-client (push) Canceled after 0s
.NET port / cpp-conformance (push) Canceled after 0s
Extend managed macOS client toward feature parity
2026-09-19 00:39:04 +02:00

3.3 KiB

Managed Apple clients

VoiceCat.Mac is the native AppKit C# port. It targets net10.0-macos27.0 and references the same VoiceCat.Core and VoiceCat.Audio assemblies used by the Windows client and managed CLI. The explicit platform version selects Microsoft's Xcode 27 preview bindings; the deployed app still supports macOS 14 and later.

The managed client now implements the Swift client's functional surface: profiles and Keychain authentication, TOFU, protected channels, hierarchical channel presentation and roster state, channel and modeless private text, microphone/auxiliary/screen-audio streams, selectable Core Audio devices, VAD/PTT/always-on input, stereo microphone, RNNoise, per-stream receive tuning, self/server mute and deafen, full channel configuration, moderation, permissions, account administration, event sounds and speech. It imports the legacy Swift profile, TOFU and Keychain state during cutover. Capture is converted to interleaved 48 kHz int16 PCM through AVAudioConverter; playback converts the shared bounded PcmRing into Core Audio's native planar Float32 layout inside an allocation-free, non-blocking AVAudioSourceNode callback.

The Swift app remains the release oracle until the managed app passes the manual VoiceOver and real multi-human call matrix. Produce and validate an ad-hoc Release bundle with zsh clients/apple/dotnet/publish-macos.sh --dry-run. The script prefers /usr/local/share/dotnet/dotnet, where the pinned Apple workload is installed; set VOICECAT_DOTNET to override that host. Signing is performed on bin/Release/distribution/VoiceCat.app, leaving MSBuild's incremental app bundle untouched. For distribution, set VOICECAT_CODESIGN_IDENTITY; setting APPLE_ID, APPLE_TEAM_ID, and APPLE_APP_PASSWORD additionally submits, staples, and Gatekeeper-validates the notarized bundle.

Build on Apple Silicon macOS 27 with Xcode 27, .NET SDK 10.0.401 and workload set 10.0.401. Homebrew protobuf supplies a native arm64 protoc; the current Grpc.Tools package contains only an x64 macOS compiler.

sudo dotnet workload install macos ios --version 10.0.401
brew install protobuf # if /opt/homebrew/bin/protoc is not already present
cmake -S dotnet/native -B dotnet/artifacts/native-build -DCMAKE_BUILD_TYPE=Release -DVOICECAT_DOTNET_RID=osx-arm64
cmake --build dotnet/artifacts/native-build --config Release --target voicecat_media --parallel 2
cmake --install dotnet/artifacts/native-build --config Release --component DotnetMedia --prefix dotnet/artifacts/native
dotnet restore clients/apple/dotnet/VoiceCat.Apple.slnx
dotnet build clients/apple/dotnet/VoiceCat.Apple.slnx -c Debug
open clients/apple/dotnet/VoiceCat.Mac/bin/Debug/net10.0-macos27.0/osx-arm64/VoiceCat.app

The native build stages an osx-arm64 libvoicecat_media.dylib; that shim contains only Opus/RNNoise. Debug builds deliberately omit hardened runtime so an ad-hoc-signed local app can load the separately ad-hoc-signed .NET runtime libraries without an Apple Development identity. Release builds retain hardened runtime for Developer ID signing and notarization. Only a macOS host can link, launch, grant microphone access and verify live devices. Final audio quality is validated with real multi-human calls after the feature surface is complete; a synthetic ten-minute sine-wave listen is deliberately not a release gate.