Есть ли публичный способ заставить MPNowPlayingInfoCenter показывать элементы управления подкаста?
Я хотел бы, чтобы Центр управления (через MPNowPlayingInfoCenter) отображал элементы управления 15 секунд назад / 15 секунд, которые Apple показывает с подкастами, например:
Полное отсутствие документации говорит мне, что нет очевидного способа сделать это, но кто-нибудь там нашел какой-нибудь неочевидный способ заставить это, не прибегая к частному методу?
Я уже настроил обработку кнопки "вперед / назад", чтобы продвигаться соответствующим образом, я просто хотел бы использовать более подходящий пользовательский интерфейс. Любая помощь будет принята с благодарностью.
4 ответа
Хорошо, так что у меня было немного времени на руках, и поэтому я последовал за крошкой... Это то, что я нашел.
Включите среду MediaPlayer и получите RemoteCommandCenter:
MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
затем, если вы хотите установить элементы пропуска в соответствии с Overcast, вы можете сделать следующее:
MPSkipIntervalCommand *skipBackwardIntervalCommand = [rcc skipBackwardCommand];
[skipBackwardIntervalCommand setEnabled:YES];
[skipBackwardIntervalCommand addTarget:self action:@selector(skipBackwardEvent:)];
skipBackwardIntervalCommand.preferredIntervals = @[@(42)]; // Set your own interval
MPSkipIntervalCommand *skipForwardIntervalCommand = [rcc skipForwardCommand];
skipForwardIntervalCommand.preferredIntervals = @[@(42)]; // Max 99
[skipForwardIntervalCommand setEnabled:YES];
[skipForwardIntervalCommand addTarget:self action:@selector(skipForwardEvent:)];
и в обработчиках событий делать то, что вам нужно сделать, чтобы пропустить интервал:
-(void)skipBackwardEvent: (MPSkipIntervalCommandEvent *)skipEvent
{
NSLog(@"Skip backward by %f", skipEvent.interval);
}
-(void)skipForwardEvent: (MPSkipIntervalCommandEvent *)skipEvent
{
NSLog(@"Skip forward by %f", skipEvent.interval);
}
Примечание. Свойство prefeIntervals является NSArray, но я не выяснил, каким образом дополнительные интервалы могут быть использованы командным центром, если вы сами ничего не сделаете с этим.
Вещи, чтобы отметить, что я нашел до сих пор. Когда вы делаете это, вы берете на себя управление всеми элементами управления, поэтому кнопки воспроизведения и паузы по умолчанию не будут отображаться, если вы не сделаете то же самое для них:
MPRemoteCommand *pauseCommand = [rcc pauseCommand];
[pauseCommand setEnabled:YES];
[pauseCommand addTarget:self action:@selector(playOrPauseEvent:)];
//
MPRemoteCommand *playCommand = [rcc playCommand];
[playCommand setEnabled:YES];
[playCommand addTarget:self action:@selector(playOrPauseEvent:)];
(Существует также определенный togglePlayPauseCommand, но я не могу заставить его срабатывать из командного центра - хотя он и срабатывает из наушников.)
Другие открытия: кнопки находятся в фиксированном положении слева / в середине / вправо, поэтому вы не можете иметь (например) previousTrack и skipBackward, так как они оба занимают левую позицию.
Существуют команды seekForward / seekBackward, для которых требуется запуск команд prevTrack и nextTrack. Когда вы настраиваете и то, и другое, одно нажатие вызывает следующий / предыдущий, а нажатие и удержание запускают поиск начала и конца поиска, когда вы поднимаете палец.
// Doesn’t show unless prevTrack is enabled
MPRemoteCommand *seekBackwardCommand = [rcc seekBackwardCommand];
[seekBackwardCommand setEnabled:YES];
[seekBackwardCommand addTarget:self action:@selector(seekEvent:)];
// Doesn’t show unless nextTrack is enabled
MPRemoteCommand *seekForwardCommand = [rcc seekForwardCommand];
[seekForwardCommand setEnabled:YES];
[seekForwardCommand addTarget:self action:@selector(seekEvent:)];
-(void) seekEvent: (MPSeekCommandEvent *) seekEvent
{
if (seekEvent.type == MPSeekCommandEventTypeBeginSeeking) {
NSLog(@"Begin Seeking");
}
if (seekEvent.type == MPSeekCommandEventTypeEndSeeking) {
NSLog(@"End Seeking");
}
}
Есть также механизм обратной связи, которого я раньше не видел (занимает левую позицию)
MPFeedbackCommand *likeCommand = [rcc likeCommand];
[likeCommand setEnabled:YES];
[likeCommand setLocalizedTitle:@"I love it"]; // can leave this out for default
[likeCommand addTarget:self action:@selector(likeEvent:)];
MPFeedbackCommand *dislikeCommand = [rcc dislikeCommand];
[dislikeCommand setEnabled:YES];
[dislikeCommand setActive:YES];
[dislikeCommand setLocalizedTitle:@"I hate it"]; // can leave this out for default
[dislikeCommand addTarget:self action:@selector(dislikeEvent:)];
BOOL userPreviouslyIndicatedThatTheyDislikedThisItemAndIStoredThat = YES;
if (userPreviouslyIndicatedThatTheyDislikedThisItemAndIStoredThat) {
[dislikeCommand setActive:YES];
}
MPFeedbackCommand *bookmarkCommand = [rcc bookmarkCommand];
[bookmarkCommand setEnabled:YES];
[bookmarkCommand addTarget:self action:@selector(bookmarkEvent:)];
// Feedback events also have a "negative" property but Command Center always returns not negative
-(void)dislikeEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
NSLog(@"Mark the item disliked");
}
-(void)likeEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
NSLog(@"Mark the item liked");
}
-(void)bookmarkEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
NSLog(@"Bookmark the item or playback position");
}
Это отображает три горизонтальные полосы и вызывает лист предупреждений - вы можете выделить их по отдельности, установив активное свойство.
Также определена рейтинговая команда, но я не смог ее отобразить в командном центре
// MPRatingCommand *ratingCommand = [rcc ratingCommand];
// [ratingCommand setEnabled:YES];
// [ratingCommand setMinimumRating:0.0];
// [ratingCommand setMaximumRating:5.0];
// [ratingCommand addTarget:self action:@selector(ratingEvent:)];
и команда изменения скорости воспроизведения - но снова не удалось заставить это показать в Командном центре
// MPChangePlaybackRateCommand *playBackRateCommand = [rcc changePlaybackRateCommand];
// [playBackRateCommand setEnabled:YES];
// [playBackRateCommand setSupportedPlaybackRates:@[@(1),@(1.5),@(2)]];
// [playBackRateCommand addTarget:self action:@selector(remoteControlReceivedWithEvent:)];
Существует также механизм целевого действия на основе блоков, если вы предпочитаете
// @property (strong, nonatomic) id likeHandler;
self.likeHandler = [likeCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent *event) {
NSLog(@"They like it");
return MPRemoteCommandHandlerStatusSuccess; // or fail or no such content
}];
Последний момент, о котором следует знать: если вы зарегистрировались для получения удаленных событий через [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; затем некоторые из этих команд также инициируют события в обработчике - (void)remoteControlReceivedWithEvent:(UIEvent *)receiveEvent. Это UIEvents, хотя с типом UIEventTypeRemoteControl и подтипом для различения события. Вы не можете смешивать и сопоставлять их с MPRemoteCommandEvents в этом методе. Есть подсказки, что MPRemoteCommandEvents заменит UIEvents в какой-то момент.
Все это основано на методах проб и ошибок, поэтому не стесняйтесь исправлять.
Gareth
Для разработчиков Swift
import MediaPlayer
let rcc = MPRemoteCommandCenter.shared()
let skipBackwardCommand = rcc.skipBackwardCommand
skipBackwardCommand.isEnabled = true
skipBackwardCommand.addTarget(handler: skipBackward)
skipBackwardCommand.preferredIntervals = [42]
let skipForwardCommand = rcc.skipForwardCommand
skipForwardCommand.isEnabled = true
skipForwardCommand.addTarget(handler: skipForward)
skipForwardCommand.preferredIntervals = [42]
func skipBackward(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
guard let command = event.command as? MPSkipIntervalCommand else {
return .noSuchContent
}
let interval = command.preferredIntervals[0]
print(interval) //Output: 42
return .success
}
func skipForward(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
guard let command = event.command as? MPSkipIntervalCommand else {
return .noSuchContent
}
let interval = command.preferredIntervals[0]
print(interval) //Output: 42
return .success
}
Другая команда была бы аналогичной и их можно проверить здесь
Oooooooh. Марко Армент заставил это поработать в Overcast и, по крайней мере, оставил для ребят из Кастро след в виде крошки:
Это MPRemoteCommandCenter. Удачи с документацией, хотя.
Вот упомянутая документация для тех, кто следит за этим вопросом - я предполагаю, что это связано с skipBackwardCommand
а также skipForwardCommand
, У меня нет времени, чтобы изучить это в эту самую секунду, поэтому я оставлю это здесь на случай, если кто-то захочет ткнуть в это и дать более подробный ответ.
У Apple нет документации, потому что нет способа это изменить. Опять же, Apple хранит лучшие вещи при себе (Siri также приходит на ум).
Версия с джейлбрейком поддерживает изменение кнопок Центра управления, которые я нашел на этом сайте. У меня такое ощущение, что вы хотите использовать это приложение на реальной iOS 7, а не на джейлбрейкнутой версии, так что это вам совсем не поможет.
Эти частные API слишком часто мешают разрабатывать хорошие приложения. Если Apple не предоставит нам больше свободы в использовании в настоящее время частных API, вам не повезло.
В дополнение к другим ответам я обнаружил, что если я не установил nowPlayingInfo в MPNowPlayingInfoCenter, то кнопки пропуска не появлялись, но появлялись кнопки nextTrack и PreviousTrack по умолчанию. (появляются простые кнопки быстрой перемотки вперед и назад) Убедитесь, что вы устанавливаете MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo в какой-то момент, как показано ниже:
var songInfo: NSMutableDictionary = [
MPMediaItemPropertyTitle: "song title",
MPMediaItemPropertyArtist: "artist ",
MPNowPlayingInfoPropertyElapsedPlaybackTime: "0"
]
MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = songInfo as [NSObject : AnyObject]