Developers use sound in iOS and macOS apps to create unique experiences that engage the user. This post presents an overview of configuring an AVAudioSession, loading a local sound file, and playing a sound using AVPlayer in Swift:

  1. Get A Local Sound File URL
  2. Configure An AVAudioSession
    a. AVSession.Category.soloAmbient
    b. AVSession.Category.ambient
    c. AVSession.Category.playback
  3. Activate An AVAudioSession
  4. Play A Sound Or Sound Effect
  5. Play A Sound On Button Press
  6. Loop Audio Or Sound
  7. Stop Playing A Sound

Get A Local Sound File URL

The first step to load a sound file. Often audio and sound effects are bundled with an iOS or macOS application:

// Load a sound file URL
guard let soundFileURL = Bundle.main.url(
    forResource: "sound effect", withExtension: "mp3"
) else {
    throw SoundError.fileNotFound
}

This example uses a custom Swift error SoundError.fileNotFound. Read Create, Throw, and Handle Custom Errors in Swift to learn more about custom errors.

Configure An AVAudioSession

The next step is to configure an AVAudioSession with an AVSession.Category. The AVSession.Category helps inform iOS and macOS how your sound should be played. Some common AVSession.Category options are:

AVSession.Category.soloAmbient

The default category. Your audio will be played by itself muting other audio, and your audio will be silenced by locking the screen and Silent switch.

try AVAudioSession.sharedInstance().setCategory(
    AVAudioSession.Category.soloAmbient
)

AVSession.Category.ambient

Your audio will be played with other audio, if any other audio is playing, and your audio will be silenced by locking the screen and Silent switch.

try AVAudioSession.sharedInstance().setCategory(
    AVAudioSession.Category.ambient
)

AVSession.Category.playback

Your audio will be played by itself muting other audio, and your audio ignores the Silent switch and will continue even if the screen locks.

try AVAudioSession.sharedInstance().setCategory(
    AVAudioSession.Category.playback
)

The AVSession.Category.playback category can also be configured to play alongside any other sounds currently playing:

// Play alongside other sounds
try AVAudioSession.sharedInstance().setCategory(
    AVAudioSession.Category.playback, 
    options: AVAudioSession.CategoryOptions.mixWithOthers
)
// Play and reduce the volume of other sounds
try AVAudioSession.sharedInstance().setCategory(
    AVAudioSession.Category.playback, 
    options: AVAudioSession.CategoryOptions.duckOthers
)

For the examples in this post the category AVSession.Category.playback will be used.

Activate An AVAudioSession

After configuring an AVAudioSession, use the setActive(_:, options:) method on an AVAudioSession to attempt to activate the session. This method can fail, for example, if another app or the system has priority on the audio currently playing.

do {
    // Attempts to activate session so you can play audio, 
    // if other sessions have priority this will fail
    try AVAudioSession.sharedInstance().setActive(true)
} catch let error {
    // Handle error 
}

Play A Sound Or Sound Effect

A sound file or sound effect can be played once the AVAudioSession is configured and activated.

// The soundFileURL is a local URL to the sound file
// that should be played
let player = try AVAudioPlayer(contentsOf: soundFileURL)
player.play()

Play A Sound On Button Press

Combining all the steps, the following is an implementation of an IBAction playSound() that plays a sound file sound effect.mp3 when a button is pressed:

@IBAction func playSound() {
    // Load a local sound file
    guard let soundFileURL = Bundle.main.url(
        forResource: "sound effect",
        withExtension: "mp3"
    ) else {
        return
    }
    
    do {
        // Configure and activate the AVAudioSession
        try AVAudioSession.sharedInstance().setCategory(
            AVAudioSession.Category.playback
        )

        try AVAudioSession.sharedInstance().setActive(true)

        // Play a sound
        let player = try AVAudioPlayer(
            contentsOf: soundFileURL
        )

        player.play()
    }
    catch {
        // Handle error
    }
}

Loop Audio Or Sound

A sound file or sound effect can be played in a loop using AVAudioPlayer by setting the numberOfLoops property. A value of -1 means to loop forever.

// The soundFileURL is a local URL to the sound file
// that should be played
let player = try AVAudioPlayer(contentsOf: soundFileURL)

// Play this sound on loop forever
player.numberOfLoops = -1
player.play()

Stop Playing A Sound

To stop an AVAudioPlayer from playing a sound, call the stop() method.

// Play a sound
let player = try AVAudioPlayer(
    contentsOf: soundFileURL
)
player.play()

// Stop playing a sound
player.stop()

Play A Sound From A File In Swift

That’s it! By loading a sound file from a local URL and configuring an AVSession you can play audio and sound effects in your iOS and macOS apps using Swift.