-1

I,m creating a app the use a lot of sfx and background music. But i can't find the best way to inherite this type of data through View Controllers. Do i have to initialize my audios in every view controller? But what if i want to stop a music that started in a preview VC?

This is the code that i'm using:

do {
            // Music BG
            let resourcePath = NSBundle.mainBundle().pathForResource("MusicaBg", ofType: "wav")!
            let url = NSURL(fileURLWithPath: resourcePath)
            try musicPlayer = AVAudioPlayer(contentsOfURL: url)

            // SFX for Button

            let resourcePath2 = NSBundle.mainBundle().pathForResource("botaoApertado", ofType: "wav")!
            let url2 = NSURL(fileURLWithPath: resourcePath2)
            try botaoApertado = AVAudioPlayer(contentsOfURL: url2)

        } catch let err as NSError {
            print(err.debugDescription)
        }

What's the best way to do that?

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
Zé Moreira
  • 125
  • 1
  • 2
  • 9

1 Answers1

1

You're probably looking for the Singleton pattern since you need a single canonical instance of background music, that any ViewController can interact with.

Then any time you need to change the music you simple call the corresponding method on e.g. AudioManager.sharedInstance from anywhere, and as you keep moving through the app the music will continue.

You would probably want to start the music in your AppDelegate or FirstViewController.

For example, with the code you've given, you might want something like

class AudioManager {
  static let sharedInstance = AudioManager()

  var musicPlayer: AVAudioPlayer?
  var botaoApertado: AVAudioPlayer?

  private init() {
  }

  func startMusic() {
    do {
      // Music BG
      let resourcePath = NSBundle.mainBundle().pathForResource("MusicaBg", ofType: "wav")!
      let url = NSURL(fileURLWithPath: resourcePath)
      try musicPlayer = AVAudioPlayer(contentsOfURL: url)

      // SFX for Button
      let resourcePath2 = NSBundle.mainBundle().pathForResource("botaoApertado", ofType: "wav")!
      let url2 = NSURL(fileURLWithPath: resourcePath2)
      try botaoApertado = AVAudioPlayer(contentsOfURL: url2)

    } catch let err as NSError {
      print(err.debugDescription)
    }
  }
}

func stopMusic() { // implementation
}

As soon as you write AudioManager.sharedInstance.startMusic() the sharedInstance static variable will be initialized (once, since it's a static property) and then startMusic() will be called on it.

If you later call AudioManager.sharedInstance.stopMusic() it will use the same sharedInstance you initialized previously, and stop the music.

Post any questions you have in the comments.

Alex Popov
  • 2,509
  • 1
  • 19
  • 30
  • So i need to create a new Swift file, implement a class and subclass every time that i want to play or stop the music? – Zé Moreira Jan 05 '16 at 02:40
  • it worked! Thanks for the answer. But, so i can understand the concept better, whats the role of the sharedInstance constant in the code? I don't get it – Zé Moreira Jan 05 '16 at 16:22
  • @ZéMoreira The Singleton pattern is used when you need exactly one of something, and you want it to be accessible from multiple places. Your AudioPlayer is a perfect example, because it will be alive for the entire duration of the app, and it shouldn't matter where it's used from. The reason for `sharedInstance` is to twofold: 1. explicitly state that this "instance", or copy of the object, is shared by anyone who uses it, and 2. so you can have instance variables/functions. We guarantee there is only one by making it "static", which means that it belongs to the AudioEngine class. – Alex Popov Jan 05 '16 at 18:59
  • @ZéMoreira (ran out of comment chars) from the Swift docs: "Singletons provide a globally accessible, shared instance of an object. You can create your own singletons as a way to provide a unified access point to a resource or service that’s shared across an app, such as an audio channel to play sound effects or a network manager to make HTTP requests." If you're still confused, either read more about singletons, or just believe that this is the best way to use it for now, and you will understand how this works in time :) feel free to ask anything else, I'll do my best to help. – Alex Popov Jan 05 '16 at 19:01