I have a music app that uses the MPMusicPlayerController.
I originally wrote it using the systemMusicPlayer option under iOS 9. I had some trouble with the player not shutting down correctly under certain circumstances so I switched to the appplicationMusicPlayer (see Quitting app causes error "Message from debugger: Terminated due to signal 9")
However, as an application player, I can't get a lot of the benefits like control center handling, bluetooth data display, etc.
So, I switched back to the systemMusicPlayer. I have also changed to Xcode 9.2 and a compile target of iOS 10.3.
Now when I run my app, it can take several seconds for it to respond to controls like play/pause or next/previous. My whole UI is painfully unresponsive.
I tried switching back to applicationMusicPlayer, recompiled, and sure enough - the UI is at normal speed.
So now I'm in a crappy position - with systemMusicPlayer, the app is barely usable, but with applicationMusicPlayer I lose a ton of capabilities.
This seems directly related to either iOS 11.2.2 on my iPhone, or something to do with targeting iOS 10.3+
Does anyone have any information about what is going on and how to fix it
EDIT: I created a very basic player and it seems to work fine in either mode, so now I'm puzzled - I'll be testing other MP commands to see what the issue is but since even my UI slows down I'm not sure.
EDIT 2: I believe I've found the culprit to be NotificationCenter, and also getting States from the MPMusicPlayerController. I've updated my sample code below which shows the problem. Once running, clicking the 'next' button will be slow sometimes, but clicking 'previous' can cause delays of up to two seconds!!
Here is the basic code if you want to create a simple player. Be sure to add three buttons in the storyboard and connect them accordingly.
//
// ViewController.swift
// junkplayer
//
import UIKit
import MediaPlayer
let notificationCenter = NotificationCenter.default
let myMP:MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer
//let myMP:MPMusicPlayerController = MPMusicPlayerController.applicationMusicPlayer()
class ViewController: UIViewController {
@IBOutlet weak var xxx: UIButton!
@IBOutlet weak var nextbut: UIButton!
@IBOutlet weak var prevbut: UIButton!
var qrySongs = MPMediaQuery()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myMP.repeatMode = MPMusicRepeatMode.none
myMP.shuffleMode = MPMusicShuffleMode.off
myMP.prepareToPlay()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
stopMPNotifications()
startMPNotifications()
}
@IBAction func nextbut(_ sender: Any) {
myMP.skipToNextItem()
}
@IBAction func prevbut(_ sender: Any) {
myMP.skipToPreviousItem()
}
@IBAction func playbut(_ sender: UIButton) {
qrySongs = MPMediaQuery.songs()
myMP.setQueue(with: qrySongs)
myMP.play()
}
func startMPNotifications(){
notificationCenter.addObserver(self, selector: #selector(showNowPlaying), name: .MPMusicPlayerControllerNowPlayingItemDidChange, object: myMP)
notificationCenter.addObserver(self, selector: #selector(handlePlayState), name: .MPMusicPlayerControllerPlaybackStateDidChange, object: myMP)
myMP.beginGeneratingPlaybackNotifications()
}
func stopMPNotifications(){
notificationCenter.removeObserver(self, name: .MPMusicPlayerControllerPlaybackStateDidChange, object: myMP)
notificationCenter.removeObserver(self, name: .MPMusicPlayerControllerNowPlayingItemDidChange, object: myMP)
myMP.endGeneratingPlaybackNotifications()
}
@objc func handlePlayState(){
if myMP.playbackState == .playing {
print("handlePlayState playback state = playing")
}else{
print("handlePlayState playback state NOT playing")
}
print("handlePlayState going to shownowplaying")
showNowPlaying()
}
@objc func showNowPlaying(){
if myMP.nowPlayingItem != nil {
print("shownowplaying nowplaying not null")
}
}
}
The system music player employs the built-in Music app on your behalf. On instantiation, it takes on the current Music app state, such as the identification of the now-playing item. If a user switches away from your app while music is playing, that music continues to play.
The Music app receives the remote control events, not your app. However, the Music app responds to remote control events on your behalf. For example, if your app plays audio using the system music player, and you switch from your app to the iOS device’s Now Playing controls, the controls work as expected.
1 Restart your PC 2 Upgrade your apps or programs 3 Run Windows Defender or antivirus software to scan for virus or malware 4 Run System file checker to fix the slow issue 5 Repair or reinstall problematic apps 6 Improve computer performance by extending system or upgrading to SSD
If a user switches away from your app while music is playing, that music continues to play. The Music app then has your music player’s most recently-set repeat mode, shuffle mode, playback state, and now-playing item. Creating a new instance of MPMusicPlayerController and not specifying the player type returns a system music player.
The app seems to lock up once you start playing, but if you swipe up to show the Control Centre then dismiss it, the app starts working fine immediately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With