MRE
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("SetupMusic").onTapGesture {
setup()
}
}
.padding()
}
private func setup() {
debugPrint("Requesting access")
MPMediaLibrary.requestAuthorization { permission in
debugPrint("Setting up music player")
let musicPlayer = MPMusicPlayerController.systemMusicPlayer
musicPlayer.beginGeneratingPlaybackNotifications()
debugPrint("Initial State: \(musicPlayer.playbackState)") //MAGIC LINE!
NotificationCenter.default.addObserver(forName: .MPMusicPlayerControllerPlaybackStateDidChange, object: musicPlayer, queue: .main) { notification in
debugPrint("State changed to \(musicPlayer.playbackState)")
}
}
}
}
将“NSAppleMusicUsageDescription”添加到您的 .plist 文件中,其中包含描述您需要访问媒体播放器框架的原因的字符串值。
如果魔线被移除,通知将不会触发。 为什么会这样?
在致电
beginGeneratingPlaybackNotifications
之前,请勿致电 addObserver
。您需要先开始观察,或者创建竞争条件,在开始观察通知之前发出通知。
一般应该尽早拨打
addObserver
,并且一定要均衡地拨打removeObserver
。否则你可能会得到重复的。要正确执行此操作,如果您创建一个单独的 ViewModel 对象来处理它,则会更容易。如果您尝试在视图内部执行此操作,则很难维护通知取消订阅令牌。但无论如何,addObserver
必须是第一位。
我不会打赌
requestAuthorization
会在主队列上回调。它不承诺这一点。然而,debugPrint
会阻止其输出流,因此引入它将对竞争条件产生重大影响,就像您在此处设置的那样。