iOS - issue with rematchWithCompletionHandler in Sandbox

232 Views Asked by At

I have the following code:

   if(tappedItem.match.status == GKTurnBasedMatchStatusEnded){
        [[GameKitHelper sharedGameKitHelper] findMatchWithViewController:self delegate:self debug:false  invite:tappedItem.player];
        return;
        NSLog(@"Participants %@", [tappedItem.match.participants description]);

        [tappedItem.match rematchWithCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
         {
             if (error) {
                 NSLog(@"%@", error);
             }

             else
             {
                 [[GameKitHelper sharedGameKitHelper] setMatch:tappedItem.match];
                 [[NSNotificationCenter defaultCenter]
                  postNotificationName:ShowGameScreen
                  object:tappedItem.match];
             }

         }];
    }

I've got a number of people Beta testing it via TestFlight with sandbox enabled, but for some reason I get the following error when trying to rematch:

{GKServerStatusCode=5121, NSLocalizedDescription=The requested operation could not be completed because the player is invalid., NSUnderlyingError=0x17045cdd0 "The operation couldn’t be completed. status = 5121, Invitation from: 224002977 to: 225851510 is not allowed because they are neither friends nor have recently played"}

The match was ended properly, so it's not that:

[_match
        endMatchInTurnWithMatchData:data
        scores:scores
        achievements:nil
        completionHandler:^(NSError *error) {}];

I'm thinking this is an isolated issue with Sandbox, but unless I can test it I'm not confident that it will work in the once released.

Edit #2:

Here's the tappedItem.match object:

    <GKTurnBasedMatch 0x174250200 -
matchID:0049f124-b8c3-43d8-9964-beaf58af69f8
bundleID:--- REMOVED ---
status:GKTurnBasedMatchStatusEnded
message:''
creationDate:2015-06-24 23:12:31 +0000
currentParticipant:(null)
participants:<GKTurnBasedParticipant 0x174205450 -
playerID:G:225851510
status:Done
matchOutcome:Won
lastTurnDate:2015-06-24 23:12:32 +0000
timeoutDate:(null)>,
<GKTurnBasedParticipant 0x174205460 -
playerID:G:224002977 (local player)
status:Done
matchOutcome:Lost
lastTurnDate:2015-06-24 23:16:56 +0000
timeoutDate:(null)>
matchData.length:295
matchDataMaximumSize:65536
exchanges:(null)>

So as you can see, the match was only finished a few hours ago. This works as expected as long as they are friends, but I need to test the rematch functionality before I can put it live.

Edit #1:

I get the same error code when I use findMatchForRequest:

GKMatchRequest *request = [[GKMatchRequest alloc] init];
    if(player != NULL)
        request.recipients= [NSMutableArray arrayWithObject:player];
    request.minPlayers = 2;
    request.maxPlayers = 2;

According to the error, "they are neither friends nor have recently played", yet they have played recently.

1

There are 1 best solutions below

1
On BEST ANSWER

I am grasping at straws here, but your edit looks similar to a problem I wrestled with trying to build the array of nextParticipants at the end of a GKTurnBasedMatchTurn GameCenter: endTurnWithNextParticipants not advancing. It didn't give me a coherent error, it just kept sending the turn back to the same player. The root seemed to be: Game Center does not like it when you pass it pointers to non-mutable objects that it previously sent to you.

I had to change

NSMutableArray *nextPlayers = (NSMutableArray *)theMatch.participants;
..some sorting logic deleted for brevity...
[theMatch endTurnWithNextParticipants:nextPlayers
                          turnTimeout:GKTurnTimeoutDefault
                            matchData:updatedMatchData
                    completionHandler:^(NSError *error)
{

To:

NSMutableArray *nextParticipants = [NSMutableArray new];
for (GKTurnBasedParticipant *participant in theMatch.participants)
{
    ...some sorting logic deleted for brevity...
    [nextParticipants addObject:participant];
}

[theMatch endTurnWithNextParticipants:nextParticipants
                          turnTimeout:GKTurnTimeoutDefault
                            matchData:updatedMatchData
                    completionHandler:^(NSError *error)
{

Your code blocks don't show where you're getting player from, so it's not clear to me if these are new or re-used objects. I'm wondering if this code

if(tappedItem.match.status == GKTurnBasedMatchStatusEnded){
    [[GameKitHelper sharedGameKitHelper] findMatchWithViewController:self delegate:self debug:false  invite:tappedItem.player];

and this code

if(player != NULL)
    request.recipients= [NSMutableArray arrayWithObject:player];

are the problem. What happens if you try creating copies of the player and pass that to the rematch and findMatch calls?