Explain which permissions are needed, how they map to Info.plist/entitlements, and how signing stability affects repeated system prompts.
Needed for ScreenCaptureKit to capture system audio.
- Usage string in
Sources/VoiceMemo/Info.plist:NSScreenCaptureUsageDescription
- Grant via:
- System Settings → Privacy & Security → Screen Recording
Needed for local audio track.
- Usage string in
Sources/VoiceMemo/Info.plist:NSMicrophoneUsageDescription
File: VoiceMemo.entitlements
Current keys:
com.apple.security.app-sandboxcom.apple.security.device.audio-inputcom.apple.security.device.cameracom.apple.security.files.downloads.read-writecom.apple.security.files.user-selected.read-writecom.apple.security.network.clientcom.apple.security.personal-information.photos-library
Only add entitlements that are required by actual features; extra entitlements increase review and user trust risks.
The app identity is anchored by Bundle ID:
Info.plistCFBundleIdentifier:cn.mistbit.voicememo- Xcode target build setting
PRODUCT_BUNDLE_IDENTIFIER:cn.mistbit.voicememo
If Bundle ID changes, macOS treats the app as a new identity and will re-prompt for privacy permissions.
macOS privacy permission grants are tied to the app’s identity and signing.
For stable behavior during development:
- Keep Bundle ID stable.
- Use a stable development Team and automatic signing in Xcode.
- If you use the generated
VoiceMemo.xcodeproj, re-rungenerate_project.pyafter dependency changes to keep package references in sync.- If Xcode shows
No such modulefor a SwiftPM dependency, tryFile > Packages > Reset Package Cachesand then clean the build folder.
- If Xcode shows
Packaging script note:
package_app.shalways builds a versioned.appplus a.ziparchive indist/.- The script uses ad-hoc signing by default (
codesign --sign -) and can switch to Developer ID signing whenSIGN_IDENTITYis provided. - If
VoiceMemo.entitlementsexists, the script signs with that entitlements file to match the Xcode target more closely. - Ad-hoc signatures are not stable identities for repeated permission grants; repeated prompts are expected when running differently signed builds.
Workflow file: .github/workflows/release.yml
When you push a tag such as v1.2.3, the release workflow:
- runs
swift test - builds
dist/VoiceMemo.app - injects
CFBundleShortVersionString=1.2.3 - injects
CFBundleVersion=<GitHub run number> - creates
dist/VoiceMemo-1.2.3-macos.zip - uploads the zip and
.sha256file to GitHub Releases
For ad-hoc archive publishing, no extra secrets are required.
For Developer ID signing:
MACOS_CERTIFICATE_P12MACOS_CERTIFICATE_PASSWORDMACOS_SIGNING_IDENTITYMACOS_KEYCHAIN_PASSWORD(optional)
For notarization:
APPLE_IDAPPLE_APP_SPECIFIC_PASSWORDAPPLE_TEAM_ID
If the signing or notarization secrets are missing, the workflow still publishes an ad-hoc signed archive. That is useful for internal distribution, but external users may still hit Gatekeeper/quarantine warnings.
- Debug via Xcode with automatic signing and a fixed team.
- Use GitHub tag releases with Developer ID signing + notarization for public binary distribution.
- Use ad-hoc packaging only for quick local distribution/testing; expect permission prompts unless you switch to a stable signing identity.