0
votes

I got the sound to play just fine, but I copied someone else's code and I want to understand it. I am new to Swift and haven't gone too deep into programming in the past, so forgive my misuse of terms - I am sure my question will still be clear.

This is my code:

import UIKit
import AVFoundation

class ViewController: UIViewController{


    var xyloSound: AVAudioPlayer?


    override func viewDidLoad() {
        super.viewDidLoad()
    }


    @IBAction func Key1(_ sender: UIButton) {

        let path = Bundle.main.path(forResource: "note\(sender.tag).wav", ofType: nil)!
        let url = URL(fileURLWithPath: path)

        do {
            xyloSound = try AVAudioPlayer(contentsOf: url)
            xyloSound?.play()
        } catch {

        }

    }

}

So the line "var xyloSound: AVAudioPlayer?"...I am guessing that AVAudioPlayer is an instance of an audio player that is defined in the AVFoundation kit. So that line of code creates the audio player. My question is, why don't we write "let" instead of "var"? I learned the "let" is for constants, and it seems like we need to create one, and only one, audio player, which sounds like it's a constant.

As for this line: "let path = Bundle.main.path(forResource: "note(sender.tag).wav", ofType: nil)!"

It seems like we are creating a constant, called path, which holds the value returned by the function Bundle.main.path (this function takes two arguments). From what I understand, this function returns the path of the associated file name, which is probably a string.

Now, the next line: "let url = URL(fileURLWithPath: path)"

What's the purpose of this? We already have the path of the audio file stored in "path", so why do we need any further information?

Any help would be greatly appreciated. Thank you.

2
someone else's code is pretty bad. First of all the correct syntax is Bundle.main.path(forResource: "note\(sender.tag)", ofType: “wav”).AVAudioPlayer(contentsOf: expects an URL which is not the same as a String. Bundle has got also methods related to URL: Bundle.main.url(forResource: "note\(sender.tag)", withExtension: “wav”).This avoids the additional step to create the URLvadian

2 Answers

1
votes

1- It's var not let

var xyloSound: AVAudioPlayer?

as you assign it later here

xyloSound = try AVAudioPlayer(contentsOf: url)

if you declared it let you'll get a compile error that you can't change a let variable , plus optional let is not even applicable as it means to compiler that you'll not change it

2- You use URL here

let url = URL(fileURLWithPath: path)

as the AVAudioPlayer expects a URL type not path ( String type )

xyloSound = try AVAudioPlayer(contentsOf: url)

look here in Docs

init(contentsOf url: URL) throws
0
votes

This is what works for me:

let url = Bundle.main.url(forResource: "note\(sender.tag)", withExtension: "wav")