Playing audio is an important part of many apps. One common trick is to fade in the volume of audio playback so we don't surprise or startle the user. This year, Apple has made this much simpler to implement using AVAudioPlayer. Let's take a look.

First we'll set up a standard AVAudioPlayer, and begin playing it at a volume of 0:

guard let asset = NSDataAsset(name: "alarm") else { print("Error Loading Audio."); return }

let player: AVAudioPlayer

do {
  player = try AVAudioPlayer(data: asset.data)
} catch { print("Error Playing."); return }

player.volume = 0
player.numberOfLoops = -1

player.play()

At this point the audio is playing but we can't hear it.

Before we check out the new feature, let's review the "old" way we might do this.

Before iOS 10, macOS 10.12, and tvOS 10, fading this audio in was, well, let's just call it "verbose":

func fadeInPlayer() {
  if player.volume <= 1 - fadeVolumeStep {
    player.volume += fadeVolumeStep
    dispatchAfterDelayHelper(time: fadeVolumeStepTime) { fadeInPlayer() }
  } else {
    player.volume = 1
  }
}

fadeInPlayer()

Recursive functions, GCD delays, manually managing state. Yuck.

Thankfully, there's now a better way.

Here's all it takes:

player.setVolume(1, fadeDuration: 1.5)

This single line of code will fade in the audio from our initial volume of 0 up to 1 over a period of 1.5 seconds.

🙌

Neat!