错误:iOS 和 MPMediaPropertyPredicate 上的 MPMediaItem 下载状态使用assetURL

Posted

技术标签:

【中文标题】错误:iOS 和 MPMediaPropertyPredicate 上的 MPMediaItem 下载状态使用assetURL【英文标题】:Bug: MPMediaItem Download Status on iOS & MPMediaPropertyPredicate using assetURL 【发布时间】:2016-03-05 23:50:10 【问题描述】:

MPMedia API 中的有趣错误

我的音乐应用程序中有一个持续存在的错误,我现在终于找到了(现在我正在用 swift 重新编写它)。它有几个方面。 (使用 systemMusicPlayer)

    我认为我已将问题缩小到具有以下属性的 MPMediaItem。 MPMediaItemPropertyIsCloudItem = true assetURL = 无 ** 这两个是有道理的,但下面的极端案例(可能很常见)让我有一段时间** 前 2 项可能是真的,但我相信如果你从 iTunes 复制它,它/可以/是可播放的(它们会在我的大部分时间播放),而且无法判断。我一遍又一遍地测试了这一点,似乎是这样,但是这些 MPMediaItems 的存在可能只是有时会引起问题,或者它们很好。但你无法找出这些歌曲是什么。 如果您正在播放队列,并且 systemMusicPlayer 遇到 曲库中的歌曲但未从 iTunes 下载或复制,我相信它会自动跳过 歌曲,类似于 systemMusicPlayer.skipToNextItem(),但我认为 在内部,这是一种不同的机制。 2a。如果您使用 systemMusicPlayer.skipToPreviousItem() 并遇到一个可能会被跳过的项目,则此行为会导致基本上无法恢复的问题 - 这意味着,它不会识别您正在尝试移回队列并只是抛出错误并将队列向前移动。 2b。据我所知,当错误发生时,MPMediaItem 永远不会变成 nowPlayingItem。加载 MPMediaItem 元数据(无论它是否是本地的,无论是否在本地始终可用)都会使问题变得复杂,但尝试播放的歌曲会立即将其再次发送到队列中。

好吧,如此愚蠢和令人愤怒。

现在我的问题是:

我无法知道设备上是否有云项目(通过 iTunes)。我 / 应该 / 能够过滤掉一个项目是否有一个资产 URL,但是,这是一个保证它是本地的和可用的。

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

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

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

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

这是 ios 9.2.1、Swift 2、Xcode 7.2.1

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

【问题讨论】:

【参考方案1】:

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

let query = MPMediaQuery()
let allItems = query.items ?? []
let items = allItems.filter  $0.assetURL?.scheme?.hasPrefix("ipod") ?? false 

【讨论】:

【参考方案2】:

从 MPMediaItem.h,你可以看到只有这些是可过滤的(用 filterable 注释):

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

因此,不可能在assetURL 属性上构建任何带有条件的查询。除非您获取所有 MPMediaItems 并进行 NSArray 搜索,否则尝试在assetURL 上做任何事情都是死胡同。

同样从苹果文档中的某个地方,我模糊记得,您无论如何都无法获得云项目下载位置的信息。

但是,如果您想进一步调查云/本地问题,我建议您考虑用户的音乐设置是否打开或关闭 iCloud 音乐库并查看 MPMediaItemPropertyHasProtectedAsset。

如果目的是检测歌曲是否为本地歌曲,您可以在 isCloudItem == FALSE 和 hasProtectedAsset == FALSE 上构建查询,在这种情况下,assetURL 无关紧要。

【讨论】:

以上是关于错误:iOS 和 MPMediaPropertyPredicate 上的 MPMediaItem 下载状态使用assetURL的主要内容,如果未能解决你的问题,请参考以下文章

如何识别 ionic 和 ios 上的 401 和 408(超时)错误?

IOS:分发(发布)配置错误和崩溃

socket.io 和 node.js 400 错误请求

由于网络错误 - IMA SDK 错误和 iOS,无法从服务器请求广告

ios - Restkit 和 SSL 证书错误

iOS 错误选择器错误