title: Reliable Way to Add Sound to UIButton
body: <p>I am trying to add a tap-sound to a UIButton to play when it is pushed. So far, I've tried two methods, but none worked out quite as well as I hoped.</p>
  
  <ol>
  <li><p>I have tried using simple SystemSounds, but they are an ugly solution, as the user have no (or rather very limited) control over the audio volume.</p></li>
  <li><p>I also tried AVAudioPlayer in the following form (called in the ViewController's init method):</p>
  
  <pre><code>[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient 
                                         error:nil];
  [[AVAudioSession sharedInstance] setActive:YES error:nil];
  [[AVAudioSession sharedInstance] setDelegate:self];
  
  NSString *filePath = [[NSBundle mainBundle] 
                       pathForResource: @"button_pushed"
                                ofType: @"wav"];
  NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: filePath];
  self.buttonPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
                                                             error: nil];
  [buttonPlayer prepareToPlay];
  [buttonPlayer setDelegate: self];
  </code></pre></li>
  </ol>
  
  <p>This second method seemed to work a lot better than the first one; especially when I called sound with the following statement:</p>
  
  <pre><code>    if (self.clickPlayer.playing) {
          [self.clickPlayer stop];
          self.clickPlayer.currentTime = 0;
          [self.clickPlayer play];
      }
      else {
          [self.clickPlayer play];
      }
  </code></pre>
  
  <p>The above ensured that I got a very fast response when I pushed the button repeatedly. Fast response time, by the way, is essential in my app, and unfortunately, this is where this second methods fails.</p>
  
  <p>If I let the application idle for about 10 seconds, loading the first sound takes a noticeable delay (then, it becomes fast and responsive again). Not only that, it also delays the button from being pushed with it. While this delay is very tiny (probably the fraction of a second), unfortunately it does effect the usability of my application. It is as if the sound was becoming deallocated automatically and needed to be initialized or put into the memory every time I did not use it for a while.</p>
  
  <p><strong>Is there a workaround to always keep the sound available and avoid the delay or another, possibly simple, method to implement button sounds?</strong></p>
  
  <p>A few more info:
  1. I use ARC
  2. I do not use IB
  3. Currently, there are no audio delegate methods implemented
  4. The ability to play audio in the background from other applications is kind of important
  5. The delay occurred on an iPhone 5; so, I can only imagine how long it would take on less powerful devices...</p>