From iPhone log:
chanora_flutter: AVAudioSession setup failed:
Error Domain=NSOSStatusErrorDomain Code=561017449
'Session activation failed'
Error code 561017449 = AVAudioSessionErrorCodeCannotStartPlaying
(ASCII '!cat' big-endian). iOS 17+ refuses setActive(true) calls
made before the app's scene is foregrounded: the audio policy
server denies the activation because the app is not yet considered
the foreground priority owner. didFinishLaunchingWithOptions runs
BEFORE the scene becomes .active, so synchronous activation there
hits this race on cold launch.
Symptom flow:
1. App cold-launch -> AppDelegate.didFinishLaunching fires
2. setActive(true) -> Error 561017449
3. Audio session is left inactive
4. cpal's later attempts to open RemoteIO see an inactive
session and reject with StreamConfigNotSupported
5. voice_join fails at ensure_audio_running
6. user sees the audio failure manifested as missing mute /
continuous / PTT buttons (now fixed in f1f81a3 to be
lenient; this commit also unblocks the underlying audio).
Fix: split the AVAudioSession configuration into two phases:
* setCategory at didFinishLaunching (always safe).
* setActive(true) deferred to UIApplication.didBecomeActive Notification, which fires after the cold-launch settle and
on every resume-from-background. Repeated setActive while
already-active is a no-op per docs.
This is the canonical iOS voice-app pattern (Discord, Zoom,
FaceTime, Flutter's package all follow it). Documented
in commit body comments.
flutter build ios --release --no-codesign: 13.2 s, Runner.app
30.0 MB.