Я пытаюсь создать пример звукового приложения с интеграцией CarPlay.Приложение представляет собой тестовый проект - без API, без потоковой передачи, без сложного пользовательского интерфейса.Просто краткий список названий песен с возможностью выбора и воспроизведения.Моя цель - обработать обратный вызов при нажатии кнопки воспроизведения на экране «Сейчас исполняется» и воспроизвести файл.
У меня нет проблем с настройкой MPPlayableContentManager, MPPlayableContentDataSource и MPPlayableContentDelegate.Мой контент анализируется из файла JSON, и он правильно отображается на экране симулятора.
// MARK: - MPPlayableContentDataSource methods
extension PlayableContentManager: MPPlayableContentDataSource {
func numberOfChildItems(at indexPath: IndexPath) -> Int {
if indexPath.count == 0 {
return playlists.count
} else if indexPath.count == 1 {
return playlists[indexPath.first ?? 0].playlist.count
} else if indexPath.count == 2 {
return playlists.last?.playlist.count ?? 0
}
return 0
}
func contentItem(at indexPath: IndexPath) -> MPContentItem? {
if indexPath.count == 1 {
return createTabbar(item: playlists[indexPath.first ??
0].name.capitalized, itemType: playlists[indexPath.first ?? 0].type)
} else if indexPath.count == 2 {
if indexPath.first == 0 {
return createContent(item: playlists[0].playlist[indexPath.last
?? 0], isContainer: false, isPlayable: true)
} else {
return createContainerContent(item: playlists[indexPath.first
?? 0].playlist[indexPath.last ?? 0])
}
}
return createTabbar(item: "", itemType: nil)
}
}
Этот код дает следующий графический вывод:
Симулятор CarPlay
Две вкладки содержат два списка воспроизведения.В каждом плейлисте есть несколько песен.
Когда я нажимаю на песню, приложение становится приложением «Сейчас исполняется», но только если я одновременно начал и закончил получать события дистанционного управления во время взаимодействия пользователя со строкой.
Метод initiatePlaybackOfContentItemAt вызывается при обнаружении щелчка по строке таблицы.
// MARK: - MPPlayableContentDelegate methods
extension PlayableContentManager: MPPlayableContentDelegate {
func playableContentManager(_ contentManager:
MPPlayableContentManager, initiatePlaybackOfContentItemAt indexPath:
IndexPath, completionHandler: @escaping (Error?) -> Void) {
DispatchQueue.main.async {
UIApplication.shared.beginReceivingRemoteControlEvents()
self.infoCenter.nowPlayingInfo = self.setupNowPlayingInfo(for:
indexPath)
completionHandler(nil)
UIApplication.shared.endReceivingRemoteControlEvents()
}
}
}
Это единственный код, который работает для меня, если я хочу приложениедля перехода к экрану «Сейчас исполняется».Если я размещу какой-либо из методов UIApplication где-либо еще, приложение перестанет реагировать на прикосновения строк и не откроет экран «Сейчас исполняется».
Однако, я думаю, потому что я вызываю endReceivingRemoteControlEvents () , я не могу получить обратный вызов для различных событий.Теперь информация о воспроизведении установлена, я вижу кнопку воспроизведения в пользовательском интерфейсе, но когда я нажимаю ее, обратный вызов не выполняется.
private func setupPlaybackCommands() {
commandCenter = MPRemoteCommandCenter.shared()
commandCenter.playCommand.addTarget { [unowned self] event in
if self.audioPlayer.rate == 0.0 {
self.play()
return .success
}
return .commandFailed
}
....
}
Экран воспроизведения сейчас
Что я делаю не так?
Может ли это быть как-то связано с тем, что я тестирую на симуляторе?Будет ли это работать на реальном устройстве?
Если кто-то может пролить свет на то, как правильно настроить интеграцию CarPlay, чтобы войти в экран «Сейчас исполняется» и ответить на события, поделитесь, пожалуйста.У меня много проблем с поиском любых полезных примеров кода или примеров.
Я знаю, что могу, но я не подал заявку на получение разрешения CarPlay, потому что этот проект предназначен только для исследовательских целей, и я сильно сомневаюсь, что я 'получу одобрение.