I have done a lot of research, both on Google and StackOverflow. All the answers I found do not work in iOS 7. I started writing fresh app in iOS 7 SDK with Xcode 5.
All
I managed to solve this, and to save hair pulling by another poor soul here goes:
Firstly make sure your Info.plist correctly lists audio as a background mode.
(If you dont know what i'm talking about select YOURAPPNAME-Info.plist select that. Click oin the plus sign and add a new key called UIBackgroundModes
and expand it. Add a value called audio
.)
You'll need a reference to whatever playback object is creating the audio. Since I'm only playing audio and AVplayer was not abiding by the background audio, use this in your view controller's header:
@property (nonatomic, retain) MPMoviePlayerController *audioPlayer;
In the implementation, do the following:
[super viewDidAppear:animated];
//Once the view has loaded then we can register to begin recieving controls and we can become the first responder
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
and
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
//End recieving events
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
add two methods
//Make sure we can recieve remote control events
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void) registerForAudioObjectNotifications {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver: self
selector: @selector (handlePlaybackStateChanged:)
name: MixerHostAudioObjectPlaybackStateDidChangeNotification
object: audioObject];
}
now ALL important code - this enables your app to control audio from "control center" and from lock screen:
- (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
if (receivedEvent.type == UIEventTypeRemoteControl) {
switch (receivedEvent.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
[self playOrStop: nil];
break;
default:
break;
}
}
}
you can add many many types of Event types here and call any method.
Typical events are:
UIEventSubtypeRemoteControlPlay = 100, //Parent EVENT
// All below are sub events and you can catch them using switch or If /else.
UIEventSubtypeRemoteControlPause = 101,
UIEventSubtypeRemoteControlStop = 102,
UIEventSubtypeRemoteControlTogglePlayPause = 103,
UIEventSubtypeRemoteControlNextTrack = 104,
UIEventSubtypeRemoteControlPreviousTrack = 105,
UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
UIEventSubtypeRemoteControlEndSeekingBackward = 107,
UIEventSubtypeRemoteControlBeginSeekingForward = 108,
UIEventSubtypeRemoteControlEndSeekingForward = 109,
To Debug help you can use:
MPMoviePlayerController *mp1= (MPMoviePlayerController *)[notification object];
NSLog(@"Movie State is: %d",[mp1 playbackState]);
switch ([mp1 playbackState]) {
case 0:
NSLog(@"******* video has stopped");
break;
case 1:
NSLog(@"******* video is playing after being paused or moved.");
break;
case 2:
NSLog(@"******* video is paused");
break;
case 3:
NSLog(@"******* video was interrupted");
break;
case 4:
NSLog(@"******* video is seeking forward");
break;
case 5:
NSLog(@"******* video is seeking Backwards");
break;
default:
break;
and thats it - hope it helps some one out there! - this is working perfect on iOS 7 and iOS 6 with Storyboard app as well as control using Headphone and all new control centre too.