(GKMatch GKVoiceChat) - both Players get disconnected after didFindMatch is called

235 views Asked by At

I'm trying to achieve VoiceChat among two connected players using GKMatch object. My players are authenticated and I'm also able to create a match using GKMatchmakerViewController.

The issue is when I receive a GKMatch object via delegate callback matchmakerViewController:didFindMatch:, I setup AudioSession and a VoiceChat object. But soon after this method is returned I get callback in GKMatch's delegate match:player:didChangeState:

Here's how I'm creating AudioSession and VoiceChat in didFindMatch callback:

- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match {

    [viewController dismissViewControllerAnimated:YES completion:nil];

    self.match = match;
    match.delegate = self;

    if (!_matchStarted && match.expectedPlayerCount == 0)
    {
        NSError *err = nil;
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];
        [audioSession setActive: YES error:&err];

        if (err)
        {
            NSLog(@"%@",err.localizedDescription);
        }
        self.teamChannel = [[match voiceChatWithName:@"redTeam"] retain];

        _teamChannel.volume = 1.0f;
        _teamChannel.active = YES;

        [_teamChannel start];

        _teamChannel.playerStateUpdateHandler = ^(NSString *playerID, GKVoiceChatPlayerState state) {
            switch (state)
            {
                case GKVoiceChatPlayerSpeaking:
                    NSLog(@"Speaking...");
                    break;
                case GKVoiceChatPlayerSilent:
                    break;
                    case GKVoiceChatPlayerConnected:
                    NSLog(@"Connected.");
                    break;
                    case GKVoiceChatPlayerConnecting:
                    NSLog(@"Connecting..");
                    break;
                    case GKVoiceChatPlayerDisconnected:
                    NSLog(@"Disconnected.");
                    break;
            }
        };
    }
}

I never get a call in playerStateUpdateHandler. I get disconnected call in the following function: `- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state { if (_match != match) return;

switch (state) {
    case GKPlayerStateConnected:
        NSLog(@"Player connected!");
        break;
    case GKPlayerStateDisconnected:
        NSLog(@"Player disconnected!");
        _matchStarted = NO;
        break;
    case GKPlayerStateUnknown:
        NSLog(@"Player stage Unknown.");
        break;
}

}`

Question:-

I'm unable to hear any audio on any end, am I missing something ? I've been trying this for 3 days now, and (as a side question) I'm not sure what to do with my second player. As, when there's a match I get didFindMatch on one of the device's and there's no call-back on the other device. Do I need to send a message on the other device ? about the match ?

A quick help would be very much appreciated.

1

There are 1 answers

0
ryan.tait On

It sounds like you are inviting a player rather than auto matching one, if this is the case didFindMatch is only called on the hosting device. The client finds out about this in the inviteHandler

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) 
{
    if (acceptedInvite)
    {
        GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite];
        mmvc.matchmakerDelegate = self;

        // Do client connection stuff here
    }
    else if (playersToInvite)
    {
        GKMatchRequest *request = [[GKMatchRequest alloc] init];
        request.minPlayers = 2;
        request.maxPlayers = 2;
        request.playersToInvite = playersToInvite;

        GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithMatchRequest:request];
        mmvc.matchmakerDelegate = self;

        [pViewController presentViewController:mmvc animated:YES completion:nil];
    }
};

If you are auto matching your game both players will receive a callback inside [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error)

 [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error) 
{
    if (error != nil)
    {
        NSLog(@"MULTIPLAYER MATCH REQUEST FAILED: %@", error.localizedDescription);
    }
    else if (match != nil)
    {
        self.m_pMatchObject = [match retain];
    }
}];