RemoteControlReceivedWithEvent is called on an iOS 7.0 device, but not iOS 8.0

I have an application that plays audio in the background. I'm trying to fix a bug when the audio controls (play / pause) on the main screen (etc.) do NOT work on iOS 8.0+, but FINE works on iOS 7.0. I dig around trying to understand what the problem is and what they are empty. Any ideas are greatly appreciated. This is what I have in place.

In the project settings: I guaranteed that UIBackgroundModes installed on audio .

In AppDelegate.h: I have a member for AVAudioSession* session; , as well as AVPlayer *audioPlayer;

In 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 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; 

}

+5
source share
2 answers

Finally it turned out that I had. In the end, it seemed that the events from Remote Control on the main screen never got into my application and did not reach my controllers. I have finished subclassing UIWindow so that I can see which events make their way through the chain. Since UIWindow is a UIResponder , I also added - (void)remoteControlReceivedWithEvent:(UIEvent *)event to a subclass. Then in makeKeyAndVisible I added:

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

I started the debugger, and -(void)makeKeyAndVisible never called! Then I searched for my application delegate for the window variable, and the string [window makeKeyAndVisible]; was not found anywhere! I added it back (as it should be there) and presto events are routed to the correct locations, such as magic. Why this works on some versions of iOS and not others, and without any other noticeable problems, goes beyond me.

Hope this helps someone in the future.

+8
source

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...") } 
+4
source

Source: https://habr.com/ru/post/1207173/


All Articles