I saw people use: [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
to handle remote control event when managing audio session.
My question:
Does this code only can be used in either a UIViewController
class or AppDelegate
class? Because I see everyone in Internet using it in one of the two classes. Can I use it in a class which is not subclass of UIViewController or AppDelegate?
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
can be used at any point in your application, such as right before starting audio playback, or on launch in application:didFinishLaunchingWithOptions:
delegate method.
For applications that want to use the controls for background audio playback throughout the entire application lifecycle (and backgrounded), I would recommend calling beginReceivingRemoteControlEvents
in your AppDelegate. That way, you're explicitly ready to receive remote control events at any time during the application lifecycle.
Palpatim mentioned MPRemoteCommandCenter
. As someone who has built a complete application around background audio playback (think radio), I would highly recommend this method over the old UIEvent
callbacks. I dive into this approach in another answer, but the gist is use MPRemoteCommandCenter.sharedCommandCenter()
to enable or disable playback controls on the lock screen and control center, as well as provide selectors:
let commandCenter = MPRemoteCommandCenter.sharedCommandCenter()
commandCenter.previousTrackCommand.enabled = true;
commandCenter.previousTrackCommand.addTarget(self, action: #selector(previousTrack))
commandCenter.nextTrackCommand.enabled = false
commandCenter.nextTrackCommand.addTarget(self, action: #selector(nextTrack))
Note that if you explicitly want to disable controls, you must provide a [dummy] selector for the action in addition to setting enabled = false
on the command.
To address your point about becomeFirstResponder
:
Any object that inherits from UIResponder, such as a UIViewController
or the UIApplicationDelegate
can become the first responder, as long as that object implements the required method remoteControlReceivedWithEvent:
to handle the remote control events. For example, I could have the AppDelegate become the first responder and handle all remote control events in there, and send out notifications that a UIViewController
listens to to pause the player or skip to the next track. You could have a UIViewController
become the first responder (the controller holding a reference to the player) and control the player directly. The architecture is pretty open and it really depends on how you structured your application. You haven't provided any code, so I don't know what your player setup looks like.
Your UIResponder
handling code will probably look something like this:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
if (event.type == UIEventTypeRemoteControl) {
switch (event.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
// Pause or play action
break;
case UIEventSubtypeRemoteControlNextTrack:
// Next track action
break;
case UIEventSubtypeRemoteControlPreviousTrack:
// Previous track action
break;
case UIEventSubtypeRemoteControlStop:
// Stop action
break;
default:
// catch all action
break;
}
}
}
Again, whether you place this in a controller or in your AppDelegate is up to you.
Can I use it in a class which is not subclass of UIViewController or AppDelegate?
Yes, you implement this in any class that inherits from UIResponder
. People normally use the AppDelegate or a view controller for convenience.
For apps that only want to handle remote control events while in a certain state--ready to play media, for example, as opposed to being on the settings or registration screen--invoking beginReceivingRemoteControlEvents
from a view controller makes a certain amount of sense. Other apps may wish to suppress remote control behavior altogether (because they take over the audio session and don't want background audio being triggered by the user and corrupting session data).
However, there's nothing that prevents you from factoring that behavior into another area of the app, especially if it is shared. beginReceivingRemoteControlEvents
is a method on UIApplication
, so as long as you're able to get a handle to [UIApplication sharedApplication]
, you can flag the app to begin/end remote control event handling.
However, it's worth noting that method is deprecated:
In iOS 7.1 and later, use the shared MPRemoteCommandCenter object to register for remote control events. You do not need to call this method when using the shared command center object. [1]
My experience with remote control event handling is a couple of years old at this point, but I recall there was some non-intuitive behavior dealing with beginReceivingRemoteControlEvents
. A quick glance at MPRemoteCommandCenter makes this look like a better API for handling remote control events. If your use cases don't require iOS 7.0 support, you should investigate that API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With