Bug:使用 assetURL 在 iOS 和 MPMediaPropertyPredicate 上下载 MPMediaItem 状态

sol*_*oid 5 mpmediaitem mpmediaquery ios swift

MPMedia API 中的有趣错误

我的音乐应用程序中存在一个持续存在的错误,我现在终于找到了它(现在我正在快速重写它)。它有几个方面。(使用系统音乐播放器)

  1. 我想我已经将问题范围缩小到具有以下属性的 MPMediaItem。
    • MPMediaItemPropertyIsCloudItem = true
    • 资产URL = nil
    • ** 这两个是有道理的,但是下面的极端情况(很可能很常见)让我困惑了一段时间**
    • 前两项可能是真的,但我相信如果你从 iTunes 复制它,它/可以/可以播放(它们对我来说大部分时间都会播放),但没有办法告诉你。我已经反复测试过这一点,似乎确实如此,但这些 MPMediaItems 的存在可能只会有时导致问题,或者它们很好。但你无法找出这些是哪些歌曲。
  2. 如果您正在播放队列,并且 systemMusicPlayer 在您的库中遇到一首歌曲但未从 iTunes 下载或复制,我相信它会自动跳过该歌曲,类似于 systemMusicPlayer.skipToNextItem(),但我认为在内部这是一个不同的机制。
    • 2a. 如果您正在使用 systemMusicPlayer.skipToPreviousItem() 并遇到一个本来会被跳过的项目,这种行为会导致基本上不可恢复的问题 - 这意味着,它无法识别您正在尝试移回队列并只是抛出错误并将队列向前移动。
    • 2b. 据我所知,当继续发生错误时,MPMediaItem 永远不会变成 nowPlayingItem。向后的问题因 MPMediaItem 元数据(无论是否在本地都始终可用)被加载而变得更加复杂,但尝试播放的歌曲会立即再次将其向前发送到队列中。

好吧,真是愚蠢又令人气愤。

现在回答我的问题:

对于无法知道云项目是否在设备上(通过 iTunes)的情况,我无能为力。但是,我/应该/能够过滤掉某个项目是否具有 assetURL,这保证了它是本地的且可用。

let filter:MPMediaPropertyPredicate = MPMediaPropertyPredicate(value: "ipod", forProperty: MPMediaItemPropertyAssetURL, comparisonType: MPMediaPredicateComparison.Contains)
Run Code Online (Sandbox Code Playgroud)

这将返回 0 个项目。有谁知道过滤此属性的方法?在这里这样做似乎是最干净的,并且应该让查询返回 items 和 itemSections。我的所有表都是从查询中填充的,我认为没有一种方法可以手动重建表。

URL 的格式如下:ipod-library://item/item.m4a?id=5314739480586915369

现在,我怀疑在填充表视图等时可以添加捕获,但感觉真的很混乱。

这是 ios 9.2.1、Swift 2、Xcode 7.2.1

我还没有擦手机并重新复制歌曲。如果 assetURL 不存在,则从音乐应用程序手动下载它们是项目获取 assetURL 的唯一方法。

Jim*_*Dee 3

它效率不高,但您可以做一件事:

let query = MPMediaQuery()
let allItems = query.items ?? []
let items = allItems.filter { $0.assetURL?.scheme?.hasPrefix("ipod") ?? false }
Run Code Online (Sandbox Code Playgroud)