Ошибка: статус загрузки MPMediaItem на iOS и MPMediaPropertyPredicate с использованием assetsURL

Забавная ошибка в MPMedia API

У меня была постоянная ошибка в моем музыкальном приложении, которую я, наконец, выследил сейчас (теперь, когда я быстро переписываю ее). Он имеет несколько граней. (используя systemMusicPlayer)

  1. I think I have narrowed the issues down to an MPMediaItem that has the following properties.
    • MPMediaItemPropertyIsCloudItem = true
    • ресурсURL = ноль
    • ** эти два случая имеют смысл, но следующий угловой случай (ну, вероятно, довольно распространенный) сбил меня с толку на некоторое время **
    • Первые 2 пункта могут быть правдой, но я считаю, что если вы скопировали его из iTunes, он /может/ воспроизводиться (у меня они будут играть большую часть времени), и нет никакого способа сказать. Я проверял это снова и снова, и кажется, что это так, но эти MPMediaItems своим существованием могут только иногда вызывать проблемы, или они в порядке. Но вы не можете узнать, что это за песни.
  2. If you are playing a queue, and systemMusicPlayer comes across a song in your library but not downloaded or copied form iTunes, I believe it will automatically skip the song, similar to systemMusicPlayer.skipToNextItem(), but I think internally it's a different mechanism.
    • 2a. This behavior causes a basically unrecoverable problem if you are using systemMusicPlayer.skipToPreviousItem() and come across an Item that would have been skipped over - meaning, it doesn't recognize that you are trying to move back in the queue and just throws the error and moves the queue forward.
    • 2б. Насколько я мог судить, когда возникает ошибка, MPMediaItem никогда не становится nowPlayingItem. Проблемы с возвратом назад усугубляются загрузкой метаданных MPMediaItem (которые всегда доступны независимо от того, являются ли они локальными или нет), но песня, пытающаяся воспроизвести, немедленно снова отправляет ее вперед в очереди.

Ладно, так глупо и бесит.

Теперь мой вопрос:

Я ничего не могу поделать с невозможностью узнать, находится ли облачный элемент на устройстве или нет (через iTunes). Однако я /должен/ иметь возможность просто отфильтровать, если элемент имеет ресурсURL, что является гарантией того, что он является локальным и доступным.

let filter:MPMediaPropertyPredicate = MPMediaPropertyPredicate(value: "ipod", forProperty: MPMediaItemPropertyAssetURL, comparisonType: MPMediaPredicateComparison.Contains)

Это возвращает 0 элементов. Кто-нибудь знает способ фильтрации по этому свойству? Кажется, что сделать это здесь было бы самым чистым и оставить запрос, возвращающий элементы и itemSections. Все мои таблицы заполняются из запросов, и я не думаю, что есть способ восстановить их вручную.

URL-адрес имеет следующий формат: ipod-library://item/item.m4a?id=5314739480586915369.

Теперь я подозреваю, что можно добавить перехваты при заполнении табличных представлений и тому подобное, но это выглядит очень грязно.

Это iOS 9.2.1, Swift 2, Xcode 7.2.1.

Я еще не протирал телефон и не переписывал песни. Загрузка их вручную из приложения «Музыка» — это единственный способ получить URL-адрес актива, если он отсутствует.


person solenoid    schedule 05.03.2016    source источник


Ответы (2)


Это не так эффективно, но одну вещь вы можете сделать:

let query = MPMediaQuery()
let allItems = query.items ?? []
let items = allItems.filter { $0.assetURL?.scheme?.hasPrefix("ipod") ?? false }
person Jimmy Dee    schedule 28.10.2016

Из MPMediaItem.h вы можете видеть, что фильтруются только они (прокомментированы с возможностью фильтрации):

MPMediaItemPropertyPersistentID
MPMediaItemPropertyMediaType
MPMediaItemPropertyTitle
MPMediaItemPropertyAlbumTitle
MPMediaItemPropertyAlbumPersistentID
MPMediaItemPropertyArtist
MPMediaItemPropertyArtistPersistentID
MPMediaItemPropertyAlbumArtist
MPMediaItemPropertyAlbumArtistPersistentID
MPMediaItemPropertyGenre
MPMediaItemPropertyGenrePersistentID
MPMediaItemPropertyCompose
MPMediaItemPropertyComposerPersistentID
MPMediaItemPropertyIsCompilation
MPMediaItemPropertyIsCloudItem
MPMediaItemPropertyHasProtectedAsset
MPMediaItemPropertyPodcastTitle
MPMediaItemPropertyPodcastPersistentID
MPMediaItemPropertyPlayCount

Таким образом, невозможно создать какой-либо запрос с условием для свойства assetsURL. Попытка что-либо сделать с assetsURL ведет в тупик, если вы не извлечете все MPMediaItems и не выполните поиск NSArray.

Также откуда-то из документов Apple, я смутно помню, вы никоим образом не можете получить информацию о том, где загружен облачный элемент или нет.

Однако, если вы хотите больше узнать об облачных/локальных проблемах, я предлагаю вам принять во внимание настройку музыки пользователя, если музыкальная библиотека iCloud включена или выключена, и просмотреть MPMediaItemPropertyHasProtectedAsset.

Если цель состоит в том, чтобы определить, является ли песня местной или нет, вы можете просто построить запрос как для isCloudItem == FALSE, так и для hasProtectedAsset == FALSE, в этом случае assetsURL не имеет значения.

person AMGuru    schedule 05.07.2018