How to play a sound using Swift? How to play a sound using Swift? ios ios

How to play a sound using Swift?


Most preferably you might want to use AVFoundation. It provides all the essentials for working with audiovisual media.

Update: Compatible with Swift 2, Swift 3 and Swift 4 as suggested by some of you in the comments.


Swift 2.3

import AVFoundationvar player: AVAudioPlayer?func playSound() {    let url = NSBundle.mainBundle().URLForResource("soundName", withExtension: "mp3")!    do {        player = try AVAudioPlayer(contentsOfURL: url)        guard let player = player else { return }        player.prepareToPlay()        player.play()    } catch let error as NSError {        print(error.description)    }}

Swift 3

import AVFoundationvar player: AVAudioPlayer?func playSound() {    guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else { return }    do {        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)        try AVAudioSession.sharedInstance().setActive(true)        let player = try AVAudioPlayer(contentsOf: url)        player.play()    } catch let error {        print(error.localizedDescription)    }}

Swift 4 (iOS 13 compatible)

import AVFoundationvar player: AVAudioPlayer?func playSound() {    guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else { return }    do {        try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)                    try AVAudioSession.sharedInstance().setActive(true)        /* The following line is required for the player to work on iOS 11. Change the file type accordingly*/        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)        /* iOS 10 and earlier require the following line:        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */        guard let player = player else { return }        player.play()    } catch let error {        print(error.localizedDescription)    }}

Make sure to change the name of your tune as well as the extension.The file needs to be properly imported (Project Build Phases > Copy Bundle Resources). You might want to place it in assets.xcassets for greater convenience.

For short sound files you might want to go for non-compressed audio formats such as .wav since they have the best quality and a low cpu impact. The higher disk-space consumption should not be a big deal for short sound files. The longer the files are, you might want to go for a compressed format such as .mp3 etc. pp. Check the compatible audio formats of CoreAudio.


Fun-fact: There are neat little libraries which make playing sounds even easier. :)
For example: SwiftySound


For Swift 3 :

import AVFoundation/// **must** define instance variable outside, because .play() will deallocate AVAudioPlayer /// immediately and you won't hear a thingvar player: AVAudioPlayer?func playSound() {    guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else {        print("url not found")        return    }    do {        /// this codes for making this app ready to takeover the device audio        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)        try AVAudioSession.sharedInstance().setActive(true)        /// change fileTypeHint according to the type of your audio file (you can omit this)        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)        // no need for prepareToPlay because prepareToPlay is happen automatically when calling play()        player!.play()    } catch let error as NSError {        print("error: \(error.localizedDescription)")    }}

The best practice for local assets is to put it inside assets.xcassets and you load the file like this :

func playSound() {    guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else {        print("url not found")        return    }    do {        /// this codes for making this app ready to takeover the device audio        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)        try AVAudioSession.sharedInstance().setActive(true)        /// change fileTypeHint according to the type of your audio file (you can omit this)        /// for iOS 11 onward, use :        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)        /// else :        /// player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)        // no need for prepareToPlay because prepareToPlay is happen automatically when calling play()        player!.play()    } catch let error as NSError {        print("error: \(error.localizedDescription)")    }}


iOS 12 - Xcode 10 beta 6 - Swift 4.2

Use just 1 IBAction and point all the buttons to that 1 action.

import AVFoundationvar player = AVAudioPlayer()@IBAction func notePressed(_ sender: UIButton) {    print(sender.tag) // testing button pressed tag    let path = Bundle.main.path(forResource: "note\(sender.tag)", ofType : "wav")!    let url = URL(fileURLWithPath : path)    do {        player = try AVAudioPlayer(contentsOf: url)        player.play()    } catch {        print ("There is an issue with this code!")    }}