xcode - MPNowPlayingInfoCenter info is not display

2019-01-14 10:14发布

问题:

I'm developing a music application, which should play music in the background.

I use the MPMoviePlayerController to play the music. My code to initiate the MPMoviePlayerController:

NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
resourcePath = [resourcePath stringByAppendingString:@"/music.m4a"];
NSError* err;
self.player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:resourcePath]];
if (err) {
    NSLog(@"ERROR: %@", err.localizedDescription);
}
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
[session setActive:YES error:nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self.player setShouldAutoplay:NO];
[self.player setControlStyle: MPMovieControlStyleEmbedded];
self.player.view.hidden = YES;
[self.player prepareToPlay];

When I execute [self.player play]; the music starts. But I also want to display the name of the song, the name of the album and the album artwork in the LockScreen and the ControlCenter. I'm using the following code:

Class playingInfoCenter = NSClassFromString(@"MPNowPlayingInfoCenter");
    if (playingInfoCenter) {
        NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init];
        MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage: [UIImage imageNamed:@"artwork.png"]];
        [songInfo setObject:@"SongName" forKey:MPMediaItemPropertyTitle];
        [songInfo setObject:@"ArtistName" forKey:MPMediaItemPropertyArtist];
        [songInfo setObject:@"AlbumTitle" forKey:MPMediaItemPropertyAlbumTitle];
        [songInfo setObject:albumArt forKey:MPMediaItemPropertyArtwork];
        [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
    }

But nothing gets displayed in the LockScreen. It doesn't get displayed in the ControlCenter either.

How can I solve my problem? I didn't find anything on the internet.

Thanks in advance, Fabian.

回答1:

The problem is that you are not satisfying the requirements to become master of the lock screen and control center, as I explain in my book. You should be seeing the modern (iOS 8) equivalent of this:

The fact that you are not seeing it suggests that you are omitting one or more of the requirements, which I list (quoting directly from my book here):

  • Your app must contain a UIResponder in its responder chain that returns YES from canBecomeFirstResponder, and that responder must actually be first responder.
  • Some UIResponder in the responder chain, at or above the first responder, must implement remoteControlReceivedWithEvent:.
  • Your app must call the UIApplication instance method beginReceivingRemoteControlEvents.
  • Your app’s audio session’s policy must be Playback.
  • Your app must be emitting some sound.

I don't know which of those you are omitting; it could be more than one. You might like to compare your code with a working example, here:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/iOS7bookExamples/bk2ch14p653backgroundPlayerAndInterrupter/backgroundPlayer/backgroundPlayer/ViewController.m



回答2:

Want to expand @matt's answer - setting nowPlayingInfo is useless when you use AVAudioSessionCategoryOptionMixWithOthers option.



回答3:

Expanding further on @matt's answer, it's required that you call endReceivingRemoteControlEvents and resignFirstResponder when the app comes back into the foreground (applicationDidBecomeActive). Otherwise the OS assumes you are a bad actor (or forgot to turn them off) and turns off your ability to show the sleep controls entirely, even after you call beginReceivingRemoteControlEvents again. I added these calls and now the Sleep Controls always show when they should.