title: iOS text-to-speech in background
body: <p>I am having an intermittent (aargh!) problem playing Text-to-Speech in the background, triggered from Apple Watch. I have properly set up the background mode, the AVSession category, and the WatchKitExtensionRequest handler. (See below.) I had this working before, and can't figure out what changed. (Could it be iOS 9 has issues? "Before" means, among other things, iOS 8.)</p>
  
  <p>The problem is this: when the app gets the request from the Watch and the app is either in the background or the phone is sleeping (locked), the speech <em>sometimes</em> plays right away, and <em>other times</em> doesn't play until the app is brought to the foreground. The OS seems to be sometimes queuing the audio, and sometimes not. I can't find any common thread between success and failure cases. I can verify with logging that the call to speakUtterance() <em>is</em> being made in <em>all</em> situations. But its behavior varies, apparently randomly. The only clue is that it <em>might</em> be the case that the longer the app is in the background, the less likely it is to speak right away.</p>
  
  <p>This is making me pull my hair out. Suggestions welcome.</p>
  
  <h2>In info.plist:</h2>
  
  <p>Required background modes: App plays audio or streams audio/video using AirPlay</p>
  
  <h2>In AppDelegate.application:didFinishLaunching:withOptions():</h2>
  
  <pre><code>do {
      try AVAudioSession.sharedInstance().setCategory(
          AVAudioSessionCategoryPlayback, 
          withOptions:.DuckOthers
      )
      try AVAudioSession.sharedInstance().setActive(true)
  } catch let error as NSError {
      // etc...
  }
  </code></pre>
  
  <h2>In AppDelegate.application:handleWatchKitExtensionRequest...():</h2>
  
  <pre><code>var bgTaskId:UIBackgroundTaskIdentifier = 0
  bgTaskId = application.beginBackgroundTaskWithName(
      "Prose WKE handler",
      expirationHandler: {
          application.endBackgroundTask(bgTaskId)
      }
  )
  //... Post notification to call Text-to-Speech
  application.endBackgroundTask(bgTaskId)
  </code></pre>