首页 > 解决方案 > func removeFilterPredicate(_ predicate: MPMediaPredicate) 无法始终如一地工作

问题描述

我在尝试时遇到了一个不一致的问题func removeFilterPredicate(_ predicate: MPMediaPredicate)但是我在尝试时从来没有遇到过问题func addFilterPredicate(_ predicate: MPMediaPredicate)

当我测试我的应用程序并添加谓词时,它每次都可以正常工作。当我尝试删除谓词时,它通常会起作用,但有时不会。

我期望的行为是删除谓词,然后播放与前一个谓词不匹配的随机歌曲

实际上有时发生的事情是在我删除谓词并跳到下一首歌曲后,上一个谓词中的更多歌曲仍在播放

我发现如果我想保证它失败,我可以通过添加谓词以仅播放特定艺术家的歌曲然后快速跳过几首歌曲然后尝试删除谓词来做到这一点。

我添加谓词的方式是

func getSongsWithCurrentArtistFor(item: MPMediaItem) -> MPMediaQuery {
  let artistPredicate = MPMediaPropertyPredicate(value: item.artist, forProperty: MPMediaItemPropertyArtist, comparisonType: .contains)
  let query = MPMediaQuery()
  query.addFilterPredicate(artistPredicate)
  return query
}


let lockArtist = MediaManager.shared.getSongsWithCurrentArtistFor(item: nowPlaying)
  if var items = lockArtist.items {
    items.shuffle()
    let descriptor = MPMusicPlayerMediaItemQueueDescriptor(itemCollection: MPMediaItemCollection(items: items))
    self.mediaPlayer.prepend(descriptor)
   }

再次永不失败

要删除谓词:

func removeArtistLockFor(item: MPMediaItem) -> MPMediaQuery {
  let artistPredicate = MPMediaPropertyPredicate(value: item.artist, forProperty: MPMediaItemPropertyArtist)
  let query = MPMediaQuery()
  query.removeFilterPredicate(artistPredicate)
  return query
}

let unlockArtist = MediaManager.shared.removeArtistLockFor(item: nowPlaying)
  if var items = unlockArtist.items?.filter({ (item) -> Bool in
    return item.mediaType.rawValue <= MPMediaType.anyAudio.rawValue
      }) {
      items.shuffle()
       let descriptor = MPMusicPlayerMediaItemQueueDescriptor(itemCollection: MPMediaItemCollection(items: self.newSongs.shuffled()))
       self.mediaPlayer.prepend(descriptor)
 }

我想知道是否 A)我删除的方式存在问题MPMediaPropertyPredicate,B)我需要某种附加方法来修复快速变化的歌曲的边缘情况,或者 C)两者兼而有之。

我知道我之前曾发布过有关 MPMediaPlayer 的问题 .. 特别是关于func prepend(_ descriptor: MPMusicPlayerQueueDescriptor)但这些问题已在 ios13 中得到解决。这是一个新问题......添加谓词总是有效的事实让我认为这更多的是我的错误,而不是Apple的问题......?

标签: swift

解决方案


removeArtistLockFor函数中的行

let query = MPMediaQuery()
  query.removeFilterPredicate(artistPredicate)

...似乎正在创建 MPMediaQuery 的新实例,因此除非它的行为类似于单例(从文档中似乎并非如此),否则此时将没有什么可删除的。

您是否应该在添加谓词并将其传递给删除函数时保留对查询的引用,以便您可以执行

passedQuery.removeFilterPredicate(artistPredicate)

推荐阅读