Compare commits

...

4 Commits

Author SHA1 Message Date
jorgenhenrichsen 0d4060eb68 Merge pull request #14 from jorgenhenrichsen/remote-commands
Remote commands
2018-08-04 19:59:41 +02:00
Jørgen Henrichsen 15a8bc4abd Bumped pod version 2018-08-04 19:53:59 +02:00
Jørgen Henrichsen da5b7702f7 Use next/prev commands in the example. 2018-08-04 08:55:44 +02:00
Jørgen Henrichsen 0066a4121c Added next and previous remote commands.
Also improved error handling in the RemoteCommandController.
2018-08-04 08:55:04 +02:00
4 changed files with 119 additions and 52 deletions
+2 -2
View File
@@ -27,8 +27,8 @@ class AudioController {
player.remoteCommands = [
.stop,
.togglePlayPause,
.skipForward(preferredIntervals: [30]),
.skipBackward(preferredIntervals: [30]),
.next,
.previous,
.changePlaybackPosition
]
try? audioSessionController.set(category: .playback)
+1 -1
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'SwiftAudio'
s.version = '0.3.1'
s.version = '0.3.2'
s.summary = 'Easy audio streaming for iOS'
# This description is used to generate tags and improve search results.
+15 -5
View File
@@ -19,15 +19,19 @@ public protocol RemoteCommandProtocol {
var handlerKeyPath: KeyPath<RemoteCommandController, RemoteCommandHandler> { get }
}
public struct BaseRemoteCommand: RemoteCommandProtocol {
public struct PlayBackCommand: RemoteCommandProtocol {
public static let play = BaseRemoteCommand(id: "Play", commandKeyPath: \MPRemoteCommandCenter.playCommand, handlerKeyPath: \RemoteCommandController.handlePlayCommand)
public static let play = PlayBackCommand(id: "Play", commandKeyPath: \MPRemoteCommandCenter.playCommand, handlerKeyPath: \RemoteCommandController.handlePlayCommand)
public static let pause = BaseRemoteCommand(id: "Pause", commandKeyPath: \MPRemoteCommandCenter.pauseCommand, handlerKeyPath: \RemoteCommandController.handlePauseCommand)
public static let pause = PlayBackCommand(id: "Pause", commandKeyPath: \MPRemoteCommandCenter.pauseCommand, handlerKeyPath: \RemoteCommandController.handlePauseCommand)
public static let stop = BaseRemoteCommand(id: "Stop", commandKeyPath: \MPRemoteCommandCenter.stopCommand, handlerKeyPath: \RemoteCommandController.handleStopCommand)
public static let stop = PlayBackCommand(id: "Stop", commandKeyPath: \MPRemoteCommandCenter.stopCommand, handlerKeyPath: \RemoteCommandController.handleStopCommand)
public static let togglePlayPause = BaseRemoteCommand(id: "TogglePlayPause", commandKeyPath: \MPRemoteCommandCenter.togglePlayPauseCommand, handlerKeyPath: \RemoteCommandController.handleTogglePlayPauseCommand)
public static let togglePlayPause = PlayBackCommand(id: "TogglePlayPause", commandKeyPath: \MPRemoteCommandCenter.togglePlayPauseCommand, handlerKeyPath: \RemoteCommandController.handleTogglePlayPauseCommand)
public static let nextTrack = PlayBackCommand(id: "NextTrackCommand", commandKeyPath: \MPRemoteCommandCenter.nextTrackCommand, handlerKeyPath: \RemoteCommandController.handleNextTrackCommand)
public static let previousTrack = PlayBackCommand(id: "PreviousTrack", commandKeyPath: \MPRemoteCommandCenter.previousTrackCommand, handlerKeyPath: \RemoteCommandController.handlePreviousTrackCommand)
public typealias Command = MPRemoteCommand
@@ -85,6 +89,10 @@ public enum RemoteCommand {
case togglePlayPause
case next
case previous
case changePlaybackPosition
case skipForward(preferredIntervals: [NSNumber])
@@ -101,6 +109,8 @@ public enum RemoteCommand {
.pause,
.stop,
.togglePlayPause,
.next,
.previous,
.changePlaybackPosition,
.skipForward(preferredIntervals: []),
.skipBackward(preferredIntervals: []),
+101 -44
View File
@@ -53,27 +53,27 @@ public class RemoteCommandController {
private func enable(command: RemoteCommand) {
switch command {
case .play: self.enableCommand(BaseRemoteCommand.play)
case .pause: self.enableCommand(BaseRemoteCommand.pause)
case .stop: self.enableCommand(BaseRemoteCommand.stop)
case .togglePlayPause: self.enableCommand(BaseRemoteCommand.togglePlayPause)
case .play: self.enableCommand(PlayBackCommand.play)
case .pause: self.enableCommand(PlayBackCommand.pause)
case .stop: self.enableCommand(PlayBackCommand.stop)
case .togglePlayPause: self.enableCommand(PlayBackCommand.togglePlayPause)
case .next: self.enableCommand(PlayBackCommand.nextTrack)
case .previous: self.enableCommand(PlayBackCommand.previousTrack)
case .changePlaybackPosition: self.enableCommand(ChangePlaybackPositionCommand.changePlaybackPosition)
case .skipForward(let preferredIntervals):
self.enableCommand(SkipIntervalCommand.skipForward.set(preferredIntervals: preferredIntervals))
case .skipBackward(let preferredIntervals):
self.enableCommand(SkipIntervalCommand.skipBackward.set(preferredIntervals: preferredIntervals))
case .skipForward(let preferredIntervals): self.enableCommand(SkipIntervalCommand.skipForward.set(preferredIntervals: preferredIntervals))
case .skipBackward(let preferredIntervals): self.enableCommand(SkipIntervalCommand.skipBackward.set(preferredIntervals: preferredIntervals))
}
}
private func disable(command: RemoteCommand) {
switch command {
case .play: self.disableCommand(BaseRemoteCommand.play)
case .pause: self.disableCommand(BaseRemoteCommand.pause)
case .stop: self.disableCommand(BaseRemoteCommand.stop)
case .togglePlayPause: self.disableCommand(BaseRemoteCommand.togglePlayPause)
case .play: self.disableCommand(PlayBackCommand.play)
case .pause: self.disableCommand(PlayBackCommand.pause)
case .stop: self.disableCommand(PlayBackCommand.stop)
case .togglePlayPause: self.disableCommand(PlayBackCommand.togglePlayPause)
case .next: self.disableCommand(PlayBackCommand.nextTrack)
case .previous: self.disableCommand(PlayBackCommand.previousTrack)
case .changePlaybackPosition: self.disableCommand(ChangePlaybackPositionCommand.changePlaybackPosition)
case .skipForward(_): self.disableCommand(SkipIntervalCommand.skipForward)
case .skipBackward(_): self.disableCommand(SkipIntervalCommand.skipBackward)
@@ -83,49 +83,64 @@ public class RemoteCommandController {
// MARK: - Handlers
lazy var handlePlayCommand: RemoteCommandHandler = { (event) in
do {
try self.audioPlayer?.play()
return MPRemoteCommandHandlerStatus.success
if let audioPlayer = self.audioPlayer {
do {
try audioPlayer.play()
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
}
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
}
return MPRemoteCommandHandlerStatus.commandFailed
}
lazy var handlePauseCommand: RemoteCommandHandler = { (event) in
do {
try self.audioPlayer?.pause()
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
if let audioPlayer = self.audioPlayer {
do {
try audioPlayer.pause()
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
}
}
return MPRemoteCommandHandlerStatus.commandFailed
}
lazy var handleStopCommand: RemoteCommandHandler = { (event) in
self.audioPlayer?.stop()
return .success
if let audioPlayer = self.audioPlayer {
audioPlayer.stop()
return .success
}
return MPRemoteCommandHandlerStatus.commandFailed
}
lazy var handleTogglePlayPauseCommand: RemoteCommandHandler = { (event) in
do {
try self.audioPlayer?.togglePlaying()
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
if let audioPlayer = self.audioPlayer {
do {
try audioPlayer.togglePlaying()
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
}
}
return MPRemoteCommandHandlerStatus.commandFailed
}
lazy var handleSkipForwardCommand: RemoteCommandHandler = { (event) in
if let command = event.command as? MPSkipIntervalCommand,
let interval = command.preferredIntervals.first,
let audioPlayer = self.audioPlayer {
try? audioPlayer.seek(to: audioPlayer.currentTime + Double(truncating: interval))
return MPRemoteCommandHandlerStatus.success
do {
try audioPlayer.seek(to: audioPlayer.currentTime + Double(truncating: interval))
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
}
}
return MPRemoteCommandHandlerStatus.commandFailed
}
@@ -133,17 +148,48 @@ public class RemoteCommandController {
if let command = event.command as? MPSkipIntervalCommand,
let interval = command.preferredIntervals.first,
let audioPlayer = self.audioPlayer {
try? audioPlayer.seek(to: audioPlayer.currentTime - Double(truncating: interval))
return MPRemoteCommandHandlerStatus.success
do {
try audioPlayer.seek(to: audioPlayer.currentTime - Double(truncating: interval))
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
}
}
return MPRemoteCommandHandlerStatus.commandFailed
}
lazy var handleChangePlaybackPositionCommand: RemoteCommandHandler = { (event) in
if let event = event as? MPChangePlaybackPositionCommandEvent {
if let event = event as? MPChangePlaybackPositionCommandEvent,
let audioPlayer = self.audioPlayer {
do {
try self.audioPlayer?.seek(to: event.positionTime)
try audioPlayer.seek(to: event.positionTime)
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
}
}
return MPRemoteCommandHandlerStatus.commandFailed
}
lazy var handleNextTrackCommand: RemoteCommandHandler = { (event) in
if let player = self.audioPlayer as? QueuedAudioPlayer {
do {
try player.next()
return MPRemoteCommandHandlerStatus.success
}
catch let error {
return self.getRemoteCommandHandlerStatus(forError: error)
}
}
return MPRemoteCommandHandlerStatus.commandFailed
}
lazy var handlePreviousTrackCommand: RemoteCommandHandler = { (event) in
if let player = self.audioPlayer as? QueuedAudioPlayer {
do {
try player.previous()
return MPRemoteCommandHandlerStatus.success
}
catch let error {
@@ -160,8 +206,19 @@ public class RemoteCommandController {
return MPRemoteCommandHandlerStatus.noActionableNowPlayingItem
}
}
else if let error = error as? APError.LoadError {
switch error {
case .invalidSourceUrl(_):
return MPRemoteCommandHandlerStatus.commandFailed
}
}
else if let error = error as? APError.QueueError {
switch error {
case .noNextItem, .noPreviousItem, .invalidIndex(_, _):
return MPRemoteCommandHandlerStatus.noSuchContent
}
}
return MPRemoteCommandHandlerStatus.commandFailed
}
}