iOS 控制中心音乐控件在 iOS 11 更新中停止工作(remoteControlReceivedWithEvent 未调用 iOS 11)

iOS control center music controls stop working in iOS 11 update (remoteControlReceivedWithEvent is not called iOS 11)

我在使用 iOS 控制中心音乐控件时遇到问题在 iOS 11 更新之前,播放暂停按钮已启用并正常工作,正如预期的那样。

然而,在 iOS 11 它停止工作。经过研究,我发现在 IOS 11 中,remoteControlReceivedWithEvent 从未被调用,但是,在较旧的 iOS 版本中,例如 iOS 9,它被正常调用

我将活动设置在 AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Enable background audio listening
    // https://developer.apple.com/library/ios/qa/qa1668/_index.html
    NSError *error = nil;
    if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error]) {
        NSLog(@"%@", error);
    }
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}


- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
    if (receivedEvent.type == UIEventTypeRemoteControl) {
        switch (receivedEvent.subtype) {
            case UIEventSubtypeRemoteControlPlay:
                [[NSNotificationCenter defaultCenter] postNotificationName:kCYCAppDelegatePlayPauseNotificationName object:nil];
                break;
            case UIEventSubtypeRemoteControlPause:
                [[NSNotificationCenter defaultCenter] postNotificationName:kCYCAppDelegatePlayPauseNotificationName object:nil];
                break;
            case UIEventSubtypeRemoteControlTogglePlayPause:
                [[NSNotificationCenter defaultCenter] postNotificationName:kCYCAppDelegatePlayPauseNotificationName object:nil];
                break;
            default:
                break;
        }
    }
}

我还订阅了另一个 class 中的远程事件来控制 play/pause 按钮

- (void)subscribeToRemoteControlEvents {

    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.1")) {
        // Disables the forward/backward buttons and only shows the play button.
        // You can't just enable the command, you must subscribe for this to activate, so
        // the subscription in this case doesn't do anything.
        [MPRemoteCommandCenter sharedCommandCenter].togglePlayPauseCommand.enabled = YES;
        [[MPRemoteCommandCenter sharedCommandCenter].togglePlayPauseCommand addTarget:self action:@selector(ignore_removeCommandCenterFired)];
    }

    [[NSNotificationCenter defaultCenter] addObserver:self forName:kCYCAppDelegatePlayPauseNotificationName object:nil queue:nil usingBlock:^(NSNotification *note, CYCCastManager *observer) {
        if (observer.isCastPlaying) {
            [observer pause];
        }
        else {
            [observer play:NO];
        }
    }];
}

- (void)unsubscribeFromRemoteControlEvents {
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.1")) {
        [[MPRemoteCommandCenter sharedCommandCenter].togglePlayPauseCommand removeTarget:self action:@selector(ignore_removeCommandCenterFired)];
    }
}

我想知道为什么不再工作了我确实检查了文档以了解 API 中的更改,但我没有看到更改

注意:我检查了以下链接,但没有成功

iOS - UIEventTypeRemoteControl events not received

https://forums.developer.apple.com/thread/84204

Unable to receive remoteControlReceivedWithEvent - objective c - ios

remoteControlReceivedWithEvent in AVAudio is not being called

remoteControlReceivedWithEvent not Called in appDelegate

最后我通过使用 remoteCommandCenter 和播放和暂停按钮而不是 tooglePlayPauseCommand 解决了这个问题

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")){
    //NOTE: this is the only way that I find to make this work on IOS 11 its seems to be that togglePlayPauseCommand is not working anymore
    MPRemoteCommandCenter* commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
    [commandCenter.playCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
        [[NSNotificationCenter defaultCenter] postNotificationName:kCYCAppDelegatePlayNotificationName object:nil];
        return MPRemoteCommandHandlerStatusSuccess;
    }];

    [commandCenter.pauseCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
        [[NSNotificationCenter defaultCenter] postNotificationName:kCYCAppDelegatePauseNotificationName object:nil];
        return MPRemoteCommandHandlerStatusSuccess;
    }];

    [[NSNotificationCenter defaultCenter] addObserver:self forName:kCYCAppDelegatePlayNotificationName object:nil queue:nil usingBlock:^(NSNotification *note, CYCCastManager *observer) {
        if (!observer.isCastPlaying) {
            [observer play:NO];
        }
    }];

    [[NSNotificationCenter defaultCenter] addObserver:self forName:kCYCAppDelegatePauseNotificationName object:nil queue:nil usingBlock:^(NSNotification *note, CYCCastManager *observer) {
        if (observer.isCastPlaying) {
            [observer pause];
        }
    }];


}

刚刚被胡安的回答修改了。

if(@available(iOS 11, *)) {
    MPRemoteCommandCenter* commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
    [commandCenter.playCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {

        [[NSNotificationCenter defaultCenter] postNotificationName:@"RemotePlayCommandNotification" object:nil];
        return MPRemoteCommandHandlerStatusSuccess;
    }];

    [commandCenter.pauseCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"RemotePauseCommandNotification" object:nil];
        return MPRemoteCommandHandlerStatusSuccess;
    }];

    [[NSNotificationCenter defaultCenter] addObserverForName:@"RemotePlayCommandNotification" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {

        NSLog(@"Clicked the play button.");
    }];

    [[NSNotificationCenter defaultCenter] addObserverForName:@"RemotePauseCommandNotification" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {

        NSLog(@"Clicked the pause button.");
    }];

}