diff --git a/apps/chanora_flutter/ios/Runner/Info.plist b/apps/chanora_flutter/ios/Runner/Info.plist index 1bc9cef..b1ba0bb 100644 --- a/apps/chanora_flutter/ios/Runner/Info.plist +++ b/apps/chanora_flutter/ios/Runner/Info.plist @@ -26,6 +26,8 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + NSMicrophoneUsageDescription + Chanora needs microphone access so you can talk on your TeamSpeak-compatible voice server. UIApplicationSceneManifest UIApplicationSupportsMultipleScenes @@ -49,6 +51,10 @@ UIApplicationSupportsIndirectInputEvents + UIBackgroundModes + + audio + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/apps/chanora_flutter/macos/Runner.xcodeproj/project.pbxproj b/apps/chanora_flutter/macos/Runner.xcodeproj/project.pbxproj index 5b7eddd..1998a6d 100644 --- a/apps/chanora_flutter/macos/Runner.xcodeproj/project.pbxproj +++ b/apps/chanora_flutter/macos/Runner.xcodeproj/project.pbxproj @@ -259,7 +259,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 2650; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 331C80D4294CF70F00263BE5 = { @@ -269,7 +269,6 @@ 33CC10EC2044A3C60003C045 = { CreatedOnToolsVersion = 9.2; LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Sandbox = { enabled = 1; @@ -390,14 +389,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; @@ -579,10 +574,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 349G7M4TQQ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=macosx*]" = ""; ENABLE_APP_SANDBOX = YES; ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; ENABLE_OUTGOING_NETWORK_CONNECTIONS = NO; @@ -728,10 +724,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 349G7M4TQQ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=macosx*]" = ""; ENABLE_APP_SANDBOX = YES; ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; ENABLE_OUTGOING_NETWORK_CONNECTIONS = NO; @@ -762,10 +759,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 349G7M4TQQ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=macosx*]" = ""; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/apps/chanora_flutter/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/apps/chanora_flutter/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 7aee463..132ce99 100644 --- a/apps/chanora_flutter/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/apps/chanora_flutter/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + com.apple.security.app-sandbox com.apple.security.cs.allow-jit com.apple.security.network.server + + com.apple.security.network.client + + com.apple.security.device.audio-input + diff --git a/apps/chanora_flutter/macos/Runner/Info.plist b/apps/chanora_flutter/macos/Runner/Info.plist index 4789daa..e59169e 100644 --- a/apps/chanora_flutter/macos/Runner/Info.plist +++ b/apps/chanora_flutter/macos/Runner/Info.plist @@ -28,5 +28,13 @@ MainMenu NSPrincipalClass NSApplication + + NSMicrophoneUsageDescription + Chanora needs microphone access so you can talk on your TeamSpeak-compatible voice server. + NSInputMonitoringUsageDescription + Chanora uses Input Monitoring so push-to-talk keys work even when other apps are focused. Chanora never records what you type — only the key you bound for talking. diff --git a/apps/chanora_flutter/macos/Runner/Release.entitlements b/apps/chanora_flutter/macos/Runner/Release.entitlements index 852fa1a..5d7d52f 100644 --- a/apps/chanora_flutter/macos/Runner/Release.entitlements +++ b/apps/chanora_flutter/macos/Runner/Release.entitlements @@ -2,7 +2,13 @@ + com.apple.security.app-sandbox + com.apple.security.network.client + + com.apple.security.device.audio-input + diff --git a/tools/macos-postbuild.sh b/tools/macos-postbuild.sh new file mode 100755 index 0000000..3bd0a65 --- /dev/null +++ b/tools/macos-postbuild.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# Post-process the Flutter macOS Release bundle so it actually launches: +# +# 1. Wrap target/release/libchanora_bridge.dylib into a proper +# chanora_bridge.framework bundle (Versions/A layout, Info.plist, +# symlinks). FRB on macOS dlopen()s chanora_bridge.framework/ +# chanora_bridge — not the plain dylib. +# 2. Rewrite the dylib's LC_ID_DYLIB so dyld resolves it as +# @rpath/chanora_bridge.framework/chanora_bridge. +# 3. Ad-hoc codesign the framework + the .app bundle. +# +# This is the macOS analogue of buildit.cmd on Windows. cocogkit / +# corrosion-style auto-integration into the Xcode project is a P1 +# carryover — for now we run this script after `flutter build macos +# --release`. +# +# Usage: +# tools/macos-postbuild.sh [Release|Debug] (defaults to Release) + +set -euo pipefail + +CONFIG="${1:-Release}" +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +APP="$REPO_ROOT/apps/chanora_flutter/build/macos/Build/Products/$CONFIG/chanora_flutter.app" +DYLIB="$REPO_ROOT/target/release/libchanora_bridge.dylib" +FW="$APP/Contents/Frameworks/chanora_bridge.framework" + +if [[ ! -d "$APP" ]]; then + echo "ERROR: app bundle not found at $APP" >&2 + echo " run \`flutter build macos --$(echo "$CONFIG" | tr '[:upper:]' '[:lower:]')\` first" >&2 + exit 1 +fi +if [[ ! -f "$DYLIB" ]]; then + echo "ERROR: bridge dylib not found at $DYLIB" >&2 + echo " run \`cargo build --release -p chanora_bridge\` first" >&2 + exit 2 +fi + +# Step 1: build the chanora_bridge.framework layout. +echo "[postbuild] wrapping bridge into chanora_bridge.framework" +rm -rf "$FW" +mkdir -p "$FW/Versions/A/Resources" +cp "$DYLIB" "$FW/Versions/A/chanora_bridge" + +cat > "$FW/Versions/A/Resources/Info.plist" << 'PLIST' + + + + + CFBundleExecutable + chanora_bridge + CFBundleIdentifier + app.chanora.bridge + CFBundleName + chanora_bridge + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleVersion + 1 + + +PLIST + +ln -sf A "$FW/Versions/Current" +ln -sf Versions/Current/chanora_bridge "$FW/chanora_bridge" +ln -sf Versions/Current/Resources "$FW/Resources" + +# Step 2: rewrite install_name so dyld finds the bundled copy. +echo "[postbuild] install_name_tool -id @rpath/chanora_bridge.framework/chanora_bridge" +install_name_tool \ + -id "@rpath/chanora_bridge.framework/chanora_bridge" \ + "$FW/Versions/A/chanora_bridge" + +# Drop a stale plain dylib if a previous build left one alongside the +# framework. +rm -f "$APP/Contents/Frameworks/libchanora_bridge.dylib" + +# Step 3: codesign. Ad-hoc identity ('-') is sufficient for local +# launches; replace with a real Developer ID when distributing. +echo "[postbuild] codesigning framework + app (ad-hoc)" +codesign --force -s - --timestamp=none "$FW/Versions/A/chanora_bridge" +codesign --force -s - --timestamp=none "$FW" +codesign --force --deep -s - --timestamp=none "$APP" + +codesign --verify --deep --strict "$APP" + +echo "[postbuild] OK: $APP is launchable"