Search code examples
swiftaudioavfoundationavaudioplayer

AVAudioPlayer() Expected declaration error


I am trying to add background music to my game. I am using AVAudioPlayer() but I am getting the "Expected declaration" error. Why am I getting this error and how can I fix it? I looked it up, but it is very broad and I couldn't find my exact problem. I hope the context of my code will help:

import SpriteKit
import GameplayKit
import AVFoundation
import UIKit

class GameScene: SKScene {
    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?

    var ButtonAudioURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: "HomeSoundtrack", ofType: "m4a")!)
    var ButtonAudioPlayer = AVAudioPlayer()
    ButtonAudioPlayer = AVAudioPlayer(contentsOfURL: ButtonAudioURL, error: nil)

    var gameArea: CGRect?

    enum gameState {
        case preGame
        case inGame
        case endGame
    }

    var currentGameState = gameState.preGame

    override init(size:CGSize) {
        let maxAspectRatio: CGFloat = 16.0/9.0
        let playableWidth = size.height / maxAspectRatio
        let margin = (size.width - playableWidth) / 2
        gameArea = CGRect(x: margin, y:0, width: playableWidth, height: size.height)

        super.init(size: size)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func didMove(to view: SKView) {
        ButtonAudioPlayer.play()
    }

Solution

  • You need to combine these two lines:

    var ButtonAudioPlayer = AVAudioPlayer()
    ButtonAudioPlayer = AVAudioPlayer(contentsOfURL: ButtonAudioURL, error: nil)
    

    into one line:

    var ButtonAudioPlayer = AVAudioPlayer(contentsOfURL: ButtonAudioURL, error: nil)
    

    But that still won't work because you can't have two class properties where one depends on the other.

    So now you need to change that line to:

    lazy var ButtonAudioPlayer = AVAudioPlayer(contentsOfURL: ButtonAudioURL, error: nil)
    

    But there is no such initializer for AVAudioPlayer in Swift. You need it to be:

    lazy var ButtonAudioPlayer = try! AVAudioPlayer(contentsOfURL: ButtonAudioURL)
    

    Note that this will crash at runtime if the URL doesn't reference a valid audio file.

    Also, it is standard in Swift to name classes, structs, and enums starting with uppercase letters. Variables, functions, cases, etc. all should start with lowercase letters.

    Also avoid NSURL in Swift. Use URL.