views:

250

answers:

1

I'm currently attempting to set up background audio for an app I'm developing for iOS 4. The app doesn't have a dedicated music player view controller, however, unlike other background audio apps such as Pandora, which makes the task a bit more confusing.

I've set the appropriate Info.plist settings correctly and have an AVAudioPlayer object in my app delegate which is accessible from everywhere. When the user plays a song, I replace the AVAudioPlayer with a new one initialized with the song and play it. This all works great, except now I have no idea how to go about supporting remote control events.

Based on Apple's documentation, I have this:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    switch(event.subtype) {
        case UIEventSubtypeRemoteControlTogglePlayPause:
            if([iPhoneAppDelegate backgroundAudioPlayer].playing)
                [iPhoneAppDelegate pauseBackgroundAudioPlayer];
            else
                [iPhoneAppDelegate playBackgroundAudioPlayer];
            break;
    }
}

The thing is, where do I put this? Apple's documentation seems to suggest this should go in some view controller somewhere, but my app has lots of view controllers and navigation controllers. Wherever I try to put this, for some reason tapping the Toggle Play/Pause button in the multitasking tray remote controls either causes the song to just pause for a moment and then unpause, or somehow causes the song to play twice.

A: 

I found a couple of solutions to receiving global remote control events on the Apple Developer Forums after a bit of searching.

One way is to subclass UIWindow and override its remoteControlReceivedWithEvent:.

The second, perhaps nicer way is to subclass UIApplication and override sendEvent:. That way, you can intercept all the remote control events and handle them there globally, and not have any other responders handle them later in the responder chain.

- (void)sendEvent:(UIEvent *)event {
     if (event.type == UIEventTypeRemoteControl) {
          // Handle event
     }
     else
          [super sendEvent:event];
}
anshuchimala