John Farkerson
John Farkerson

Reputation: 2632

Why is my AVAudioPlayer not playing?

I believe there is something that I am not getting conceptually. I created (what I think is) a singleton AudioPlayer class that extends AVAudioPlayer. The reason I did this is that since this is background music for my game, I wanted to be able to stop and start it later. Here is all the code inside it:

#import "AudioPlayer.h"
//THIS IS A SINGLETON CLASS

@implementation AudioPlayer
static AudioPlayer *audioPlayer;

+(AudioPlayer *) sharedAudioPlayer {
    return audioPlayer;
}

-(id) initWithString:(NSString *)str {
    if (!audioPlayer) {
        NSURL *soundFileURL = [NSURL fileURLWithPath:str];
        audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
        audioPlayer.numberOfLoops = -1;
    }
    return audioPlayer;
}

@end

So I accessed the class from my game's main view controller like this:

[[AudioPlayer sharedAudioPlayer] initWithString:[NSString stringWithFormat:@"%@/Music.mp3",[[NSBundle mainBundle] resourcePath]]];
[[AudioPlayer sharedAudioPlayer] play];

Nothing happens, though. What am I doing wrong?

Upvotes: 0

Views: 51

Answers (1)

wombat57
wombat57

Reputation: 1341

[AudioPlayer sharedAudioPlayer] returns a static variable, which is initial nil. Thus, when you call [[AudioPlayer sharedAudioPlayer] initWithString...] you are actually calling [nil initWithString...]. This does nothing. The normal way to do this is to init the instance in the singleton accessor.

+(AudioPlayer *) sharedAudioPlayer {
    return audioPlayer;
}

Should be

+(AudioPlayer *) sharedAudioPlayer {
    static AudioPlayer *sharedPlayer = nil;
    static dispatch_once_t onceToken = 0;
    dispatch_once(&onceToken, ^{
        sharedPlayer = [[[self class] alloc] initWithString:...];
    });
    return sharedPlayer;
} 

Then you can just call

   [[AudioPlayer sharedAudioPlayer] play];

However, notice that you are passing a parameter to your singleton constructor. This is a hint that something is wrong with your design. If the object takes a parameter, are you sure that you only ever want there to be one?

Upvotes: 1

Related Questions