我有一个函数可以返回音乐库中与当前播放的歌曲年份相同的所有歌曲。它看起来像这样:
private func loadSongsByYear() {
let query = MPMediaQuery.songs()
query.addFilterPredicate(MPMediaPropertyPredicate(value: false, forProperty: MPMediaItemPropertyIsCloudItem))
if let items = query.items {
if let yearInt = Int(year) {
songsByYear = items.filter { item in
if let itemYearNumber = item.value(forProperty: "year") as? NSNumber {
return itemYearNumber.intValue == yearInt
}
return false
}
} else {
songsByYear = items.filter { item in
return item.value(forProperty: "year") == nil
}
}
}
}
我用
ScrollView
称它为.onAppear
:
ScrollView {
//My ScrollView
}
.onAppear(perform: loadSongsByYear)
我想让它在当前播放的歌曲改变时更新,所以我添加了这个
.onRecieve
ScrollView {
//My ScrollView
}
.onAppear(perform: loadSongsByYear)
.onReceive(
NotificationCenter.default.publisher(for: .MPMusicPlayerControllerNowPlayingItemDidChange),
perform: { _ in
loadSongsByYear()
}
)
几乎可以工作,只是落后了一步。如果当前播放的歌曲是 2000 年的,然后我切换到 2001 年的歌曲,没有任何变化,但是当我第二次切换到 2002 年的歌曲时,加载 2001 年的歌曲。
我是否误解了
.onRecieve
的工作原理或我做错了什么?
NotificationCenter.Publisher
造成的。使用 async
变体也会导致相同的问题,您只能在发布通知后的下一个主线程运行循环中收到最新更新,而不是相同的运行循环。
您需要使用旧的
NotificationCenter
方法,addObserver
如果您希望能够在发布通知的同一主线程运行循环中接收通知。