Playing audio file on iOS in Swift 4

Playing audio file on iOS in Swift 4

Playing media file in apps is fun. Media usually puts constraints on system resources, but it is ok to indulge in fun once in a while. In this post we will see how to play audio in the iOS app.

Given the high impact of size on the app download, please make sure any sound file you add to project does not exceed the threshold and is well compressed with the reasonable quality

  • Adding a sound file in project

First step in producing sound in project is to add sounds file. It could be of any extension such as .mp3, .wav etc. You can simply drag and drop the file in your project directory structure. Make sure to check an option which says Copy items if needed.

To make sure everything is in place after file has been added, select a project, go to Build Phases tab and under it verify the subgroup which says Copy Bundle Resources and verify that newly added audio file does exist under it.

If audio file is not present, you can add it by pressing + button and manually selecting it from the project file system.

  • AVFoundation Framework

In order to make audio work in the app, you will have to import AVFoundation framework. Add following line in the file where you're planning to add code to play the audio

import AVFoundation
  • Using AVAudioPlayer instance to play the file

In order to play the audio file you will have to initialize the instance of AVAudioPlayer with URL of audio file in the local file system

Important to note that make sure the instance of AVAudioPlayer is not local within the scope. It has to be declared on the top in the file scope. Failure to do so will result in system deallocating created instance right after the scope and no audio will be played.

For example, its declaration will look something like this

class ViewController: UIViewController {

    var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        .......
        ....
        ..
        .
  • Playing the audio file

Next, in order to play audio we will need the full path of audio file in the local directory. Swift offers the simple way to achieve it,

Assuming out file name is openmenu.wav we can use Bundle API to get full path which takes two parameters, viz. file name and extension and outputs the full URL.

let fileURL = Bundle.main.path(forResource: "openmenu", ofType: "wav")

Note the optional nature of output file path. If file does not exist, you can ignore the further processing with error as follows,


if let fileURL = Bundle.main.path(forResource: "openmenu", ofType: "wav") {   
    print("Continue processing")
} else {
    print("Error: No file with specified name exists")
}

Now that we have full path to audio file in documents directory, we will initialize the AVAudioPlayer with this parameters

do {
    if let fileURL = Bundle.main.path(forResource: "openmenu", ofType: "wav") {
        audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: fileURL))        
    } else {
        print("No file with specified name exists")
    }
} catch let error {
    print("Can't play the audio file failed with an error \(error.localizedDescription)")
}

Please note that the initializer block wrapped in the try-catch block. The AVAudioPlayer initializer throws an error in case it's unable to initialize the instance with specified file parameters

Now we have only one essential thing left to play the audio file. Calling play() instance method on audioPlayer object. This method will generate a sound and we're all set

audioPlayer?.play()

Although there is another method - prepareToPlay which may be manually called before making a call to play, but it's not necessary based on my experience and audio can even be played by directly calling play

  • Controlling number of times to play sound in loop

AVAudioPlayer allows you to control how many times you want to play audio file in the loop. This is controlled by numberOfLoops on this instance. By default this value is 0, meaning audio will be played exactly once without any loop. You can specify any positive non-zero value x for this parameter in order to play audio exactly x+1 number of times.

For example, if I want to play audio for 2 times, I will specify the following value,

audioPlayer?.numberOfLoops = 1

There is however another option to play it in look continuously. You can set it as -1

audioPlayer?.numberOfLoops = -1

This will make set the audio to play in loop for as long as the app is running.

Hope this helps to anyone who is planning to do awesome things with iOS AVFoundation framework. If you have comments, suggestions or concerns, hit me up on Twitter. If you are stuck on any step, please feel free to message me!