// Patch the freshly-generated Capacitor iOS AppDelegate so calls DEFAULT to the loudspeaker at launch // (iOS uses the quiet earpiece otherwise). Run on Codemagic (macOS) from ios-patch.sh: // node mobile/scripts/inject-audio.js mobile/ios/App/App/AppDelegate.swift // TOLERANT: exits 0 and no-ops if the template doesn't match, so it can NEVER fail the build. // NOTE: the earpiece<->speaker TOGGLE is provided by the local Capacitor plugin package mobile/plugins/ // audio-route (registered by cap sync, like @capacitor/share). This file only sets the launch default. const fs = require('fs'); const p = process.argv[2]; if (!p || !fs.existsSync(p)) { console.log(' (AppDelegate.swift not found — audio patch skipped)'); process.exit(0); } try { let s = fs.readFileSync(p, 'utf8'); if (s.includes('.defaultToSpeaker')) { console.log(' audio launch-default already patched'); process.exit(0); } const orig = s; if (!s.includes('import AVFoundation')) { if (s.includes('import Capacitor')) s = s.replace('import Capacitor', 'import Capacitor\nimport AVFoundation'); else if (s.includes('import UIKit')) s = s.replace('import UIKit', 'import UIKit\nimport AVFoundation'); } const launch = [ ' // Default call audio to the loudspeaker (iOS uses the quiet earpiece otherwise).', ' do {', ' let audioSession = AVAudioSession.sharedInstance()', ' try audioSession.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP])', ' try audioSession.setActive(true)', ' } catch { }', '', ].join('\n'); const m = s.match(/func\s+application\([^)]*didFinishLaunchingWithOptions[^)]*\)\s*->\s*Bool\s*\{[^\n]*\n/); if (m) { const idx = m.index + m[0].length; s = s.slice(0, idx) + launch + s.slice(idx); } if (s !== orig && s.includes('.defaultToSpeaker')) { fs.writeFileSync(p, s); console.log(' AVAudioSession launch default-to-speaker injected'); } else { console.log(' (AppDelegate pattern not matched — audio patch skipped)'); } } catch (e) { console.log(' (audio patch error, skipped: ' + (e && e.message) + ')'); } process.exit(0);