0

I'm developing a radio streaming app with XCode 4.5 for iOS 6 and mainly using storyboards. I successfully made it to be able to play in background. So wherever I go from my app, whether to other tabs or even after clicking the Home button on the simulator,it keeps playing. I'm using Matt Gallagher's audio streamer, which I include in my app delegate .m file below

#pragma mark - audio streaming

    - (void)playAudio:(indoRadio *)np withButton:(NSString *)currentButton
{
    if ([currentButton isEqual:@"playbutton.png"])
    {
        [self.nowplayingVC.downloadSourceField resignFirstResponder];

        [self createStreamer:np.URL];
        [self setButtonImageNamed:@"loadingbutton.png"];
        [audioStreamer start];
    }
    else
    {
            [audioStreamer stop];
    }
}

- (void)createStreamer:(NSString *)url
{
    if (audioStreamer)
    {
        return;
    }

    [self destroyStreamer];

    NSString *escapedValue = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(nil,(CFStringRef)url,NULL,NULL,kCFStringEncodingUTF8);

    NSURL *streamurl = [NSURL URLWithString:escapedValue];
    audioStreamer = [[AudioStreamer alloc] initWithURL:streamurl];

    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(playbackStateChanged:)
     name:ASStatusChangedNotification
     object:audioStreamer];
}

- (void)playbackStateChanged:(NSNotification *)aNotification
{
    NSLog(@"playback state changed? %d",[audioStreamer isWaiting]);
    if ([audioStreamer isWaiting])
    {
        [self setButtonImageNamed:@"loadingbutton.png"];
    }
    else if ([audioStreamer isPlaying])
    {
        [self setButtonImageNamed:@"stopbutton.png"];
    }
    else if ([audioStreamer isIdle])
    {
        [self destroyStreamer];
        [self setButtonImageNamed:@"playbutton.png"];
    }
}

- (void)destroyStreamer
{
    if (audioStreamer)
    {
        [[NSNotificationCenter defaultCenter]
         removeObserver:self
         name:ASStatusChangedNotification
         object:audioStreamer];

        [audioStreamer stop];
        audioStreamer = nil;
    }
}

- (void)setButtonImageNamed:(NSString *)imageName
{
    if (!imageName)
    {
        imageName = @"playButton";
    }
    self.nowplayingVC.currentImageName = imageName;

    UIImage *image = [UIImage imageNamed:imageName];
    [self.nowplayingVC.playBtn.layer removeAllAnimations];
    [self.nowplayingVC.playBtn setImage:image forState:0];

    if ([imageName isEqual:@"loadingbutton.png"])
    {
        [self.nowplayingVC spinButton];
    }
}

The problem I got is that when I click the play button, it starts the audio streamers but doesn't change into either loading button or stop button. This makes me unable to stop the audio since the button image is not changed. And since I put an NSLog inside the playbackStateChanged: method,I know that the playback state did change. It seems like the setButtonImagedNamed: method is not firing. Any thoughts?

haebaragi
  • 1
  • 1
  • Did u try having a break point int he setButtonImageNamed method?? Check if the playBtn is not nil. – Adithya May 13 '14 at 10:10
  • @Adithya yes I tried checking whether self.radioDetailVC.playBtn == nil,and it returns TRUE. Does that mean I address the button in the wrong way? – haebaragi May 14 '14 at 01:56

3 Answers3

0

Please have look of my answer:Disabled buttons not changing image in

For a button there is normal, selected, highlighted and disabled state.

So in your case you have to handle the normal and selected state.

In the xib, set image to a button for normal and selected state.

Now in the function of playAudio instead of checking the image name check the button state as below:

- (void)playAudio:(indoRadio *)np withButton:(NSString *)currentButton
{
    if (playButton.selected)
    {
        //Stop the streaming

        //set selection NO
        [playButton setSelected:NO];
    }
    else
    {
        //Start the streaming

        //set selection YES
        [playButton setSelected:YES];
    }
}

playButton is the IBOutlet of play button.

As you have set the images in xib, so the image automatically get changed as per the state of the image

Community
  • 1
  • 1
svrushal
  • 1,612
  • 14
  • 25
  • in fact @svrushal , previously I put the codes in my question above in the view controller and it worked fine (button image changes & the streaming), but since I want it to play in background even if I navigate back to the channel list or login view, I moved the codes into my app delegate. And now the only thing not working is the setButtonImageNamed method. I just figured out that here the playBtn is nil – haebaragi May 14 '14 at 02:05
0

In case you have added the playBtn programmatically, check if the button is declared as weak or its getting released somewhere. If it is weak, make it strong.

In case the button is in the nib file, then the problem is in the IBOutlet. Redo the connection properly.

Adithya
  • 4,545
  • 3
  • 25
  • 28
  • before I set the playBtn property in my view controller as (nonatomic, retain) then I changed it to (nonatomic, strong), but still not working. As for the IBOutlet, I guess not,because it can call the playAudio method which I refer from the IBAction of the button. Just like I mentioned in my question the streaming works well, only everytime I click the button it always starts the streamer (instead of stopping it) because of the unchanged "playbutton.png" image – haebaragi May 14 '14 at 02:27
0

It turned out that the delegate didn't know which nowplayingVC I was calling. @sarp-kaya's question about Calling a UIViewController method from app delegate has inspired me. I actually have put this code in my view controller viewDidLoad:

myAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;

but I forgot to add this line:

appDelegate.nowplayingVC = self;

So, all I need to do is adding that one line and it works now. okay, so silly of me for not noticing such a basic thing. But thanks for your helps :D

Community
  • 1
  • 1
haebaragi
  • 1
  • 1