# Tonuino Manager for macOS Native SwiftUI app for managing TonUINO music cards and programming TonUINO NFC cards. ## Build Requirements: macOS 13+, Xcode 15+, and [XcodeGen](https://github.com/yonaskolb/XcodeGen). ```sh xcodegen generate open TonuinoManager.xcodeproj ``` The first launch can be built from Xcode. Select a mounted SD-card volume in the app. TonUINO firmware needs `SerialInputAsCommand` enabled for serial programming. The alternative reader path uses CryptoTokenKit and a PC/SC compatible ACR122U. For local builds, bundle standalone media tools into the built app before launching it: ```sh ./scripts/bundle-local-media-tools.sh \ ".build/DerivedData/Build/Products/Debug/Tonuino Manager.app" \ "/path/to/ffmpeg" "/path/to/yt-dlp" "/path/to/deno" "/path/to/fpcalc" ``` Audio conversion, YouTube import and AcoustID fingerprinting use only tools embedded in the app bundle. The app never searches `PATH`, Homebrew, or other system package locations. YouTube import bundles yt-dlp and Deno alongside FFmpeg; AcoustID uses bundled Chromaprint `fpcalc`. Videos can be imported as one MP3 or as one MP3 per chapter. AcoustID identification fingerprints selected audio files with bundled Chromaprint `fpcalc`, looks up recordings through AcoustID, and uses MusicBrainz release data for tags. Register an application at AcoustID and save its client key in Settings; the key is stored in the macOS Keychain. The lookup service is intended for non-commercial use and requests are rate limited. ## Universal release The release script builds arm64 and x86_64, embeds universal FFmpeg, yt-dlp, Deno and Chromaprint `fpcalc` executables, signs and notarizes the app, and creates a stapled DMG plus a Sparkle ZIP. The Sparkle feed is hosted in this Gitea repository at `appcast.xml`; its public key is embedded in the app. The corresponding private key is stored in the macOS Keychain and must never be committed. ```sh DEVELOPMENT_TEAM=TEAMID \ DEVELOPER_ID_APPLICATION='Developer ID Application: Example (TEAMID)' \ NOTARY_PROFILE=tonuino-notary \ FFMPEG_BINARY='/path/to/universal/ffmpeg' \ YTDLP_BINARY='/path/to/universal/yt-dlp_macos' \ DENO_BINARY='/path/to/universal/deno' \ FPCALC_BINARY='/path/to/universal/fpcalc' \ ./scripts/build-release.sh ``` Publish the resulting release from a clean `main` checkout after setting `APP_VERSION` and `APP_BUILD`. The publisher uses a configured Git credential helper for Gitea; alternatively, provide an API token in `GITEA_TOKEN`: ```sh APP_VERSION=1.0.0 APP_BUILD=1 ./scripts/publish-release.sh ``` The publisher creates a Gitea release, signs the Sparkle archive with the private key in Keychain, updates and pushes `appcast.xml`, and deploys the DMG and download page to `https://tonuino.maddin.app`. The website itself is static and has no JavaScript runtime dependency. FFmpeg must include `libmp3lame`. Do not use Homebrew wrappers or binaries linked to Homebrew libraries; dependencies must run from the app bundle without separately installed packages. Include the licenses and corresponding source offers for all bundled tools with releases. ## TonUINO card format Card data matches TonUINO-TNG: cookie `13 37 B3 47`, version `02`, folder, playback mode, and two special parameters. ACR122U access supports MIFARE Mini, Classic 1K/4K and Ultralight/NTAG cards. Serial programming sends the TNG `WRITECARD` command at 115200 baud.