我看到人们在管理音频会话时使用[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
来处理远程控制事件。
我的问题:
此代码是否只能用于UIViewController
类或AppDelegate
类?因为我看到互联网上的每个人都在两个类中的一个中使用它。我可以在不是UIViewController或AppDelegate的子类的类中使用它吗?
答案 0 :(得分:4)
对于只想在某种状态下处理远程控制事件的应用程序 - 例如,准备播放媒体,而不是在设置或注册屏幕上 - 从视图控制器调用beginReceivingRemoteControlEvents
有一定的道理感。其他应用可能希望完全抑制远程控制行为(因为它们接管音频会话并且不希望用户触发背景音频并破坏会话数据)。
但是,没有什么可以阻止您将该行为分解到应用程序的另一个区域,特别是如果它是共享的。 beginReceivingRemoteControlEvents
是UIApplication
上的一种方法,因此只要您能够获得[UIApplication sharedApplication]
的句柄,就可以标记该应用以开始/结束远程控制事件处理。
但是,值得注意的是该方法已被弃用:
在iOS 7.1及更高版本中,使用共享MPRemoteCommandCenter对象注册远程控制事件。使用共享命令中心对象时,无需调用此方法。 [1]
我在远程控制事件处理方面的经验目前还有几年的历史,但我记得有一些非直观的行为处理beginReceivingRemoteControlEvents
。快速浏览MPRemoteCommandCenter使其看起来像是处理远程控制事件的更好的API。如果您的用例不需要iOS 7.0支持,则应调查该API。
答案 1 :(得分:0)
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
可以在应用程序的任何位置使用,例如在开始音频播放之前,或在application:didFinishLaunchingWithOptions:
委托方法中启动时使用。
对于想要在整个应用程序生命周期(以及后台运行)中使用控件进行背景音频播放的应用程序,我建议您在AppDelegate中调用beginReceivingRemoteControlEvents
。这样,您就可以在应用程序生命周期中随时接收远程控制事件。
Palpatim提到MPRemoteCommandCenter
。作为围绕背景音频播放构建完整应用程序的人(想想无线电),我强烈推荐这种方法优于旧的UIEvent
回调。我在another answer中深入研究了这种方法,但要点是使用MPRemoteCommandCenter.sharedCommandCenter()
启用或禁用锁定屏幕和控制中心的播放控件,以及提供选择器:
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))
请注意,如果您明确要禁用控件,除了在命令上设置enabled = false
之外,还必须为操作提供[dummy]选择器。
解决关于becomeFirstResponder
:
任何继承自UIResponder的对象(例如UIViewController
或UIApplicationDelegate
)都可以成为第一个响应者,只要该对象实现了处理远程控制所需的方法remoteControlReceivedWithEvent:
事件。例如,我可以让AppDelegate成为第一个响应者并处理其中的所有远程控制事件,并发出UIViewController
监听的通知以暂停播放器或跳到下一个音轨。您可以让UIViewController
成为第一个响应者(控制器持有对玩家的引用)并直接控制玩家。该体系结构非常开放,它实际上取决于您的应用程序结构。您还没有提供任何代码,因此我不知道您的播放器设置是什么样的。
您的UIResponder
处理代码可能如下所示:
- (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;
}
}
}
同样,无论您将其置于控制器中还是AppDelegate中都取决于您。
我可以在不是UIViewController或AppDelegate的子类的类中使用它吗?
是的,您可以在任何继承自UIResponder
的类中实现此功能。人们通常使用AppDelegate或视图控制器来方便。