Remote Control Events

Remote control events let users control an app’s multimedia. If your app plays audio or video content, you might want it to respond to remote control events that originate from either transport controls or external accessories. (External accessories must conform to Apple-provided specifications.) iOS converts commands into UIEvent objects and delivers the events to an app. The app sends them to the first responder and, if the first responder doesn’t handle them, they travel up the responder chain. For more information about the responder chain, see “The Responder Chain Follows a Specific Delivery Path.”

This chapter describes how to receive and handle remote control events. The code examples are taken from the Audio Mixer (MixerHost) sample code project.

Preparing Your App for Remote Control Events

To receive remote control events, your app must do three things:

To make itself capable of becoming first responder, the view or view controller should override the canBecomeFirstResponder method of the UIResponder class to return YES. It should also send itself the becomeFirstResponder method at an appropriate time. For example, a view controller might use the becomeFirstResponder method in an override of the viewDidAppear: method, as in Listing 5-1. This example also shows the view controller “turning on” the delivery of remote control events by calling the beginReceivingRemoteControlEvents method of UIApplication.

Listing 5-1  Preparing to receive remote control events

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
 
    // Turn on remote control event delivery
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
 
    // Set itself as the first responder
    [self becomeFirstResponder];
}

When the view or view controller is no longer managing audio or video, it should turn off the delivery of remote control events. It should also resign first-responder status in the viewWillDisappear: method, as shown in Listing 5-2.

Listing 5-2  Ending the receipt of remote control events

- (void)viewWillDisappear:(BOOL)animated {
 
    // Turn off remote control event delivery
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
 
    // Resign as first responder
    [self resignFirstResponder];
 
    [super viewWillDisappear:animated];
}

Handling Remote Control Events

To handle remote control events, the first responder must implement the remoteControlReceivedWithEvent: method declared by UIResponder. The method implementation should evaluate the subtype of each UIEvent object passed in and then, based on the subtype, send the appropriate message to the object that presents the audio or video content. Listing 5-3 sends play, pause, and stop messages to an audio object. Other remote control UIEvent subtypes are possible, see UIEvent Class Reference for details.

Listing 5-3  Handling remote control events

- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
 
    if (receivedEvent.type == UIEventTypeRemoteControl) {
 
        switch (receivedEvent.subtype) {
 
            case UIEventSubtypeRemoteControlTogglePlayPause:
                [self playOrStop: nil];
                break;
 
            case UIEventSubtypeRemoteControlPreviousTrack:
                [self previousTrack: nil];
                break;
 
            case UIEventSubtypeRemoteControlNextTrack:
                [self nextTrack: nil];
                break;
 
            default:
                break;
        }
    }
}

Testing Remote Control Events on a Device

Test that your app is properly receiving and handling remote control events with the Now Playing Controls. These controls are available on recent iOS devices that are running iOS 4.0 or later. To access these controls, press the Home button twice, then flick right along the bottom of the screen until you find the audio playback controls. These controls send remote control events to the app that is currently or was most recently playing audio. The icon to the right of the playback controls represents the app that is currently receiving the remote control events.

For testing purposes, you can programmatically make your app begin audio playback and then test the remote control events by tapping the Now Playing Controls. Note that a deployed app should not programmatically begin playback; that should always be user-controlled.