Reputation: 312
New to iOS and Objective-C
, have been struggling to figure this out. I have a class that holds a strong reference to an AVAudioPlayer
object and defines a method to play an mp3 depending on the parameter 'tag', which belongs to a UIButton
. In my view controller I have a method that uses this class to play a sound when a button is pressed. But when I run the simulator and press the button, the mp3 is not being played. When I don't use the other class and make the AVAudioPlayer
belong to my ViewController
, initialize it in viewDidLoad
, and call play right in the IBAction
method, it works fine. I checked that the files are available to my project and that they are being referenced correctly in the code.
I looked around and found this and this, neither solved my problem. Here's my code
GuitarTuner.h
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface GuitarTuner : NSObject
- (void) play: (NSUInteger)tag;
@end
GuitarTuner.m
#import "GuitarTuner.h"
#import <AVFoundation/AVFoundation.h>
@interface GuitarTuner()
@property (strong, nonatomic) AVAudioPlayer *audioPlayer;
@end
@implementation GuitarTuner
- (void) play:(NSUInteger)tag
{
NSString *note;
switch (tag) {
case 0:
note = @"Low-E";
break;
case 1:
note = @"A";
break;
case 2:
note = @"D";
break;
case 3:
note = @"G";
break;
case 4:
note = @"B";
break;
case 5:
note = @"Hi-E";
break;
}
NSString *path = [[NSBundle mainBundle] pathForResource:note ofType:@"mp3"];
NSURL *soundURL = [NSURL fileURLWithPath:path];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:nil];
[self.audioPlayer play];
}
@end
ViewController.m
#import "ViewController.h"
#import "GuitarTuner.h"
@interface ViewController ()
@property (strong, nonatomic) GuitarTuner *tuner;
@end
@implementation ViewController
- (GuitarTuner *) tuner
{
if (!_tuner) return [[GuitarTuner alloc] init];
return _tuner;
}
- (IBAction)noteButton:(id)sender
{
UIButton *button = (UIButton*)sender;
[self.tuner play:button.tag];
}
@end
Thanks in advance
EDIT:
Silly mistake! Just didn't properly initialize GuitarTuner property in the getter in ViewController -- should be _tuner = [[GuitarTuner alloc] init]
Answer below works too.
Upvotes: 1
Views: 189
Reputation: 1842
Try to initialise AVAudioPlayer
like this
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:note withExtension:@"mp3"] error:&error];
UPDATE:
You give yourself your answer:
When I don't use the other class and make the AVAudioPlayer belong to my ViewController, initialize it in viewDidLoad, and call play right in the IBAction method, it works fine.
Try to alloc tuner
in viewDidLoad or create from your class GuitarTuner
a singleton and from there everything will be much easier.
Also comment this:
- (GuitarTuner *) tuner
{
if (!_tuner) return [[GuitarTuner alloc] init];
return _tuner;
}
Upvotes: 1