16

Ok I have looked into this and have tried many different ways to play a sound when a button is clicked.

How would I play a sound when a button is clicked in swift 3? I have my sound in a folder named Sounds and the name is ClickSound.mp3

shane
  • 342
  • 1
  • 5
  • 28
  • It is an old question, but it could be mentioned that it is a recommended way to use wav or caf audio formats (rather than mp3) for short sounds. – Whirlwind Feb 13 '17 at 08:05
  • @Whirlwind can you explain why? I'm actually super interested in this, since I've got an app I'm working on with short sounds where I'm currently using mp3 for them. Thanks for pointing this out to me! – SRMR Mar 01 '17 at 22:28
  • 1
    @SRMR Just google about compressed and decompressed formats on iOS. For example, a wav file has no compression, means you will get best quality, low cpu impact but big disk space consumption. So this is ideal for short sounds because they dont take up too much space on disc. On the other side, mp3 is compressed, so it will save your diskspace, means it will keep your app size low, but it will be decompressed into ram, and when decompressed it will take the same amount of space as uncompressed sound. Also decompression makes an impact on cpu in some percent... Hope this make sense for you. – Whirlwind Mar 01 '17 at 22:37
  • So mp3 is ideal for background music – Whirlwind Mar 01 '17 at 22:39
  • @Whirlwind this is great, thanks for explaining and pointing me in a direction I can track down more about now too re: compressed and decompressed formats. – SRMR Mar 01 '17 at 22:42

4 Answers4

18

User below this function

 //MARK:- PLAY SOUND
func playSound() {
    let url = Bundle.main.url(forResource: "ClickSound", withExtension: "mp3")!

    do {
        player = try AVAudioPlayer(contentsOf: url)
        guard let player = player else { return }

        player.prepareToPlay()
        player.play()
    } catch let error as NSError {
        print(error.description)
    }
}

first import AudioToolbox import AVFoundation

Hope it works :)

Amit Rawat
  • 303
  • 2
  • 6
  • fatal error: unexpectedly found nil while unwrapping an Optional value (lldb) – shane Nov 15 '16 at 15:48
  • This is the code func playSound() { let url = Bundle.main.url(forResource: "ClickSound", withExtension: "mp3")! do { let player = try AVAudioPlayer(contentsOf: url) guard player == player else { return } player.prepareToPlay() player.play() } catch let error as NSError { print(error.description) } } – shane Nov 15 '16 at 15:49
  • 1
    You should create a global reference for "player" .add var player:AVAudioPlayer? – Amit Rawat Nov 21 '16 at 07:51
  • 2
    var player: AVAudioPlayer? declare it as global. – Amit Rawat Nov 21 '16 at 07:52
14

You have to keep the player from being disposed of, get it in a property of your view controller

The only real catch is that you must store your player as a property or other variable that won't get destroyed straight away – if you don't, the sound will stop immediately.

source:

var player : AVAudioPlayer?

func playSound(){
        let path = Bundle.main.path(forResource: "alert", ofType:"mp3")!
        let url = URL(fileURLWithPath: path)

        do {
            let sound = try AVAudioPlayer(contentsOf: url)
            self.player = sound
            sound.numberOfLoops = 1
            sound.prepareToPlay()
            sound.play()
        } catch {
            print("error loading file")
            // couldn't load file :(
        }
}
Amr Lotfy
  • 2,937
  • 5
  • 36
  • 56
6

You might want to use SwiftySound. It lets you play sounds easily in Swift.

Sound.play(file: "ClickSound.mp3")
Adam
  • 26,549
  • 8
  • 62
  • 79
3

A much easier way to do this is to put the following line of code in your button pressed function (Note: Only works in sprite kit):

run(SKAction.playSoundFileNamed("ClickSound.mp3", waitForCompletion: false))

Hope this helps :)

Luke Roberts
  • 311
  • 1
  • 4
  • 15