mikeT
mikeT

Reputation: 363

Change file (url, path) automatically when clicking button in AVAudioplayer Swift Xcode

3 images per screen, each with distinct sound files "apple.wav", "orange.wav", and "ball.wav" that will play when clicked.

I have the AVAudioPlayer code but I'm trying to simplify it, so I don't have a separate function for each photo playSoundOrange(), playSoundofApple(), etc.

Trying to use the same function, but input the name of the file in the button action.

Button code:

@IBAction func OrangeButton(_ sender: UIButton) {
    print("pressed OrangeButton")
    playSoundFile(orange.wav) //having it like this would be ideal. 
}

Current func I'm trying to modify, so I'm able to use the code playSoundFile(orange.wav) for each button, and just change the parameters to (apple.wav) or (ball.wav).

var player : AVAudioPlayer?
func playSoundFile(){
    let path = Bundle.main.path(forResource: "*orange*",   ofType:"*wav*")!
    let url = URL(fileURLWithPath: path)

    do {
        let sound = try AVAudioPlayer(contentsOf: url)
        self.player = sound
        sound.numberOfLoops = 0
        sound.prepareToPlay()
        sound.play()
    } catch {
        print("error loading file")
        // couldn't load file :(
    }
}

Your help is much appreciated.

Upvotes: 0

Views: 1803

Answers (2)

mikeT
mikeT

Reputation: 363

Thanks rmaddy, for solving it. Just putting the code in full for other newbies who might benefit from it.

import UIKit
import AVFoundation
import AudioToolbox

class ViewController: UIViewController {

    var player : AVAudioPlayer?

func playSoundFile(_ soundName: String) {
    let url = Bundle.main.url(forResource: soundName, withExtension: "wav")!

    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 :(
    }
}

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }


    @IBAction func buttonPressed(_ sender: UIButton) {
        var soundName: String? = nil
        if sender.currentTitle == "john" {
            soundName = "john"
        }else if sender.currentTitle == "husain" {
                soundName = "husain"
        }else if sender.currentTitle == "tom" {
                    soundName = "tom"
             }
            if let soundName = soundName {
                playSoundFile(soundName)
            }
        }

}

Upvotes: 0

rmaddy
rmaddy

Reputation: 318824

Update your playSoundFile method to take a sound name:

func playSoundFile(_ soundName: String) {
    let url = Bundle.main.url(forResource: soundName, withExtension: "wav")!

    do {
        let sound = try AVAudioPlayer(contentsOf: url)
        self.player = sound
        sound.numberOfLoops = 0
        sound.prepareToPlay()
        sound.play()
    } catch {
        print("error loading file")
        // couldn't load file :(
    }
}

Now you only need a single button action that you can use for all three buttons.

@IBAction func buttonPressed(_ sender: UIButton) {
}

Assign that one action to all three buttons.

Since you have an outlet for each button, compare the sender property against each of your outlets to determine which filename to use:

@IBAction func buttonPressed(_ sender: UIButton) {
    var soundName: String? = nil
    if sender == orangeButton {
        soundName = "orange"
    } else if sender == appleButton {
        soundName = "apple"
    } else if sender == ballButton {
        soundName = "ball"
    }

    if let soundName = soundName {
        playSoundFile(soundName)
    }
}

Replace orangeButton, appleButton, and ballButton with the actual name of your outlets.

Upvotes: 1

Related Questions