remoteControlReceivedWithEvent called on iOS 7.0 device but not iOS 8.0

I have an application that plays audio in the background. I am trying to fix a bug where the audio controls (play/pause), on the home screen (etc.), DO NOT work on iOS 8.0+ but work FINE on iOS 7.0. I have been digging through trying to figure out what the issue is and have been coming up empty. Any ideas would be greatly appreciated. Here is what I have in place.

In the Project Settings:
I have ensured that UIBackgroundModes is set to audio.

  • Terminating app due to uncaught exception 'NSUnknownKeyException' - error
  • How to get current location at the instant UIImagePickerController captures an image?
  • IOS: one IBAction for multiple buttons
  • How to achieve dynamic UIView masking?
  • How to get user profile image from logged user with Twitter Kit/Fabric in iOS
  • Are iPhone's apps notifications going to be triggered on the Apple Watch by default, without even creating an actual Watch app?
  • In the AppDelegate.h:
    I have a member for the AVAudioSession* session; as well as the AVPlayer *audioPlayer;

    In the AppDelegate.m:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    
    self.session = [AVAudioSession sharedInstance];
    
    NSError* error = NULL;
    [self.session setCategory:AVAudioSessionCategoryPlayback error:&error];
    [self.session setActive:YES error:&error];
    
    if (error) {
        NSLog(@"AVAudioSession error: %@", [error localizedDescription]);
    }
    

    In the AudioPlayerViewController.m

    - (void)viewDidLoad {
    
    //Get the Audio
    NSURL *url = [NSURL URLWithString:self.audioUrl];
    AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
    
    //Setup the player
    self.playerItem = [AVPlayerItem playerItemWithAsset:asset];
    appDelegate.audioPlayer = [AVPlayer playerWithPlayerItem:self.playerItem];
    
    //Setup the "Now Playing"
    NSMutableDictionary *mediaInfo = [[NSMutableDictionary alloc]init];
    [mediaInfo setObject:self.title forKey:MPMediaItemPropertyTitle];
    [mediaInfo setObject:self.artist forKey:MPMediaItemPropertyArtist];
    [mediaInfo setObject:self.album forKey:MPMediaItemPropertyAlbumTitle];
    [mediaInfo setObject:[NSNumber numberWithDouble:duration ] forKey:MPMediaItemPropertyPlaybackDuration];
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:mediaInfo];
    

    }

    // Process remote control events
    - (void) remoteControlReceivedWithEvent:(UIEvent *)event {
    
    NSLog(@"AudioPlayerViewController ... remoteControlReceivedWithEvent top ....subtype: %d", event.subtype);
    
    if (event.type == UIEventTypeRemoteControl) {
    
        switch (event.subtype) {
            case UIEventSubtypeRemoteControlTogglePlayPause:
                [self togglePlayPause];
                break;
            case UIEventSubtypeRemoteControlPause:
                [self doPause];
                break;
            case UIEventSubtypeRemoteControlStop:
                [self doPause];
                break;
            case UIEventSubtypeRemoteControlPlay:
                [self doPlay];
                break;
            case UIEventSubtypeRemoteControlPreviousTrack:
                [self nextOrPrevTrack];
                break;
            case UIEventSubtypeRemoteControlNextTrack:
                [self nextOrPrevTrack];
                break;
            default:
                break;
        }
    }
    

    }

    -(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
    

    }

    - (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
    

    }

    - (BOOL) canBecomeFirstResponder {
    return YES;
    

    }

    2 Solutions Collect From Internet About “remoteControlReceivedWithEvent called on iOS 7.0 device but not iOS 8.0”

    Finally figured out the issue I was having. Ultimately it seemed that the events from the Remote Control on the home screen were never making it into my app and down to my view controllers. I ended up subclassing the UIWindow so that I could see what events were making their way through the chain. As UIWindow is a UIResponder I also added the - (void)remoteControlReceivedWithEvent:(UIEvent *)event to the subclass. Then in the makeKeyAndVisible I added the:

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
    

    I started up the debugger and the -(void)makeKeyAndVisible was never called! I then searched my app delegate for the window member variable and the [window makeKeyAndVisible]; line was nowhere to be found! I added it back in (as it should have been there) and presto events are routing to the correct locations like magic. Why this was working on some versions of iOS and not others and without any other noticeable issues is beyond me.

    Hope this helps someone out in the future.

    In your ViewController add

    override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(animated)
    
            UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
            self.becomeFirstResponder()
    }
    
    override func remoteControlReceivedWithEvent(event: UIEvent) {
            // your stuff
        }
    

    In AppDelegate add

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
    var error: NSError?
            AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: &error)
            AVAudioSession.sharedInstance().setActive(true, error: &error)
    }
    

    SWIFT 3

    UIApplication.shared.beginReceivingRemoteControlEvents()
    self.becomeFirstResponder()
    
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)
    } catch {
        print("hmmm...")
    }