2013-03-12 8 views
15

Ich mache ein paar Experimente, um etwas über GameKit zu lernen und ich habe ein einfaches Spiel und ein Interface erstellt, das die Matches meines Spielers auflistet. Ich versuche, die Möglichkeit hinzuzufügen, Spiele mit der Methode removeWithCompletionHandler: auf dem Spiel zu entfernen, aber ich habe Probleme beim Entfernen eines GKTurnBasedMatch, der in einen ungültigen Zustand eingetreten zu sein scheint.Entfernen eines GKTurnBasedMatch, das sich in einem ungültigen Zustand befindet

A po des Spiels in Frage druckt:

$0 = 0x1d590d20 <GKTurnBasedMatch 0x1d590d20 id:858d8257-cc49-4060-b1d8-38c09a929e3c status:Ended message: taken:2013-03-08 18:08:47 +0000 created:2013-03-08 03:24:14 +0000 
current:<GKTurnBasedParticipant 0x1d58c020 - id:G:1717956303 (local player) status:Invited outcome:None lastTurn:(null)> 
participants: 
    <GKTurnBasedParticipant 0x1d58bc90 - id:G:1717239488 status:Done outcome:Quit lastTurn:2013-03-08 18:08:47 +0000> 
    <GKTurnBasedParticipant 0x1d58c020 - id:G:1717956303 (local player) status:Invited outcome:None lastTurn:(null)> 
> 

Welche, dass das Spiel beendet ist, um anzuzeigen, scheint worden. Einer der Teilnehmer hat jedoch das Ergebnis: Keiner, von dem ich von der Dokumentation überzeugt bin, ist für ein beendetes Spiel ungültig. Der Versuch, das Spiel einfach zu entfernen gibt:

The requested operations could not be completed because one or more parameters are invalid.

Bei dem Versuch, die Ergebnisse zu setzen und das Spiel zu beenden gibt:

The requested operation could not be completed because the session is in an invalid state.

Ich dachte, vielleicht könnte ich das Spiel nicht entfernen, da der lokale Spieler die aktiv ist Teilnehmer, aber beide participantQuitInTurnWithOutcome:... und endTurnWithNextParticipants:... beide geben den Fehler:

The requested operation could not be completed because the session is in an invalid state.

auch. Mache ich etwas falsch oder habe ich irgendwie ein nicht entfernbares Spiel geschaffen?

P.S. Ich bin auch nicht in der Lage, die Spiele über die Game Center-Schnittstelle zu entfernen, wo sie im Abschnitt "Game Over" aufgelistet sind.

+0

Die Antwort von Henrik sollte Ihr Problem lösen. Sie müssen den Aufruf von declineInviteWithCompletionHandler aufrufen: –

Antwort

5

Leider habe ich genau den gleichen Fehler gefunden. Um anderen zu helfen, das Problem zu verstehen, können Sie in der Hoffnung, eine Lösung zu recherchieren, dies wiederherstellen, indem Sie einen Freund zu einem Spiel einladen, aber das Spiel in der ersten Runde beenden, bevor Sie diesen Zug an den eingeladenen Spieler abgeben. Dann entfernt der Host-Spieler das Spiel vom Game Center. Auf dem Gerät des eingeladenen Spielers wird eine Übereinstimmung angezeigt, die wie oben beschrieben aussieht und nicht gelöscht werden kann. Ich habe alle Arten von Problemumgehungslösungen ausprobiert.

Ich hatte noch kein Glück, aber ich werde meine Antwort mit einer Lösung aktualisieren, wenn ich eine finde. Ich versuche gerade, ein Game Center-Spiel zu liefern, und darum muss ich einen Weg finden. Ich werde in den nächsten ein oder zwei Tagen eine Schlussfolgerung haben.

UPDATE: Ich ging über meine nicht löschbaren Übereinstimmungen, und sie sind fast die gleichen wie Ihre, außer mein Spieler mit dem Eingeladenen Status hat auch das Match-Ergebnis von Won. Es scheint der Schlüssel zu sein, das Spiel in einen ungültigen Zustand zu versetzen, wenn ein Spielerstatus "Eingeladen" anstelle von "Fertig" ist, aber der Spielstatus "Beendet" lautet. Das ist das gemeinsame Element zwischen unseren beiden Fällen, und es ist ein Randfall in Apples Bizantine Game Center-Code. Es würde mich nicht überraschen, wenn sie diesen Randfall einfach vermasseln würden und erwarten würden, dass Sie "nur wissen", dass Sie die Spieler nicht in diesen Zustand versetzen sollten (zweifellos, wenn Sie ihre Dokumente genau genug lesen, werden Sie in der Lage sein Stück diese zusammen irgendwann).

Meine Schlussfolgerung ist, dass Apple einen Randfall auf ihren Händen hat, der leicht unbemerkt bleibt, weil es nur passieren kann, wenn Sie ein neues Spiel beenden, und nur wenn Sie einen Freund einladen, zwei Fälle werden Sie nicht oft testen. Auch wenn Sie die Ergebnisse nicht falsch setzen, schätze ich, dass es nie passieren wird, also haben sie es nie erwischt.

Da ich noch nicht ausgeliefert habe, werde ich meine App so konfigurieren, dass Übereinstimmungen in diesem Zustand erkannt und ignoriert werden. Ich werde der Konsole melden, wie viele Matches in diesem Zustand sind, nur damit ich sicherstellen kann, dass sie nicht über diesen Punkt hinaus wächst.Dann werde ich meinen Beendigungscode analysieren und sicherstellen, dass ich in diesem Randfall einfach nie wieder einen Treffer in diesen Zustand versetzen kann. Ich denke, angesichts dessen, was wir wissen, müssen wir proaktiv sein und nur die Tatsache aufschnappen, dass einige Spiele durchgelaufen sind.

Hoffentlich haben Sie noch nicht versandt, so dass die Übereinstimmungen der Fehler in der Game Center Sandbox-Umgebung lokalisiert werden. Tatsächlich werden die fehlerhaften Übereinstimmungen nur von Ihrem Testbenutzer in der Sandbox lokalisiert, sodass Sie diesen Benutzer einfach wegwerfen und mit einem neuen Benutzer beginnen können, nachdem Sie das Problem behoben haben. Wenn Sie meine obigen Vorschläge implementieren, sollten Sie vor dem Ausführen dieses Schritts bestätigen können, dass Ihre App ordnungsgemäß funktioniert.

Wenn jemand tatsächlich einen Weg finden kann, diese Fehler zu entfernen, sobald sie existieren, lassen Sie es uns wissen, aber ich hoffe, dass meine Vorschläge und die Identifizierung der Ursache ausreichen, um mit Ihrem Projekt fortzufahren.

+0

Ich konnte diese Fehlerübereinstimmungen entfernen, indem ich für alle Teilnehmer 'participant.matchOutcome = GKTurnBasedMatchOutcomeTied' festlegte und dann' [match removeWithCompletionHandler ...] 'aufruft. Es ist nicht etwas, was ich in meinem Code aufbewahre, aber es hat die ungültigen Spiele gelöscht. – Jon

4

Ich habe eine ähnliche Situation, wenn auch etwas anders. Ich starte ein Match, lade ein zweites Sandbox-Konto ein, um zu spielen, dann beendet der erste Spieler das Spiel und löscht das Spiel, bevor der zweite Spieler antworten kann. Wenn der zweite Spieler versucht, dann das Spiel zu beenden, erhalten sie diesen Fehler:

Error quitting match in turn: Error Domain=GKErrorDomain Code=22 "The requested operation could not be completed because the specified participant is invalid." 
UserInfo=0x1f5de800 { 
    GKServerStatusCode=5097, 
    NSUnderlyingError=0x1f58b610 "The operation couldn’t be completed. 
    status = 5097, 
    Invalid state: turn sent to playerId:1952436619 in slotIndex: 0 for sessionId: 698b074b-fa0b-4505-834f-1b4305b7eecb : expected slot state: Active but found: Inactive", 
    NSLocalizedDescription=The requested operation could not be completed because the specified participant is invalid. 
} 

So so weit wie ich kann sagen, dass geschieht, weil der nächste Teilnehmer bewegt bereits einen Status hat „Erledigt“, die ich Ich vermute, weil sie bereits beendet haben:

<GKTurnBasedMatch 0x1f532b20 id:698b074b-fa0b-4505-834f-1b4305b7eecb status:Open message: taken:2013-03-30 19:53:47 +0000 created:2013-03-30 18:29:09 +0000 
current:<GKTurnBasedParticipant 0x1f532b80 - id:G:1952433332 (local player) status:Active outcome:None lastTurn:2013-03-30 19:53:47 +0000> 
participants: 
     <GKTurnBasedParticipant 0x1f532b70 - id:G:1952436619 status:Done outcome:Lost lastTurn:2013-03-30 18:29:10 +0000> 
     <GKTurnBasedParticipant 0x1f532b80 - id:G:1952433332 (local player) status:Active outcome:None lastTurn:2013-03-30 19:53:47 +0000> 
    > 

Hoffentlich hilft dies anderen diagnostizieren, wenn nichts anderes. Würde es lieben, die Einsichten anderer zu einer Problemumgehung oder Lösung zu hören. Wenn das ein Fehler von Apple ist, scheint es sich zu lohnen, ein Radar zu archivieren.

2

Der Support von Apple Technical Developer hat das Problem bestätigt. Eingereichter Fehlerbericht. Sie auf dem Laufenden halten.

+0

Freut mich zu hören, dass jemand diesem Thema folgt. Danke, Valentyn. – Zach

+0

Irgendwelche Updates zu diesem Thema? Können Sie bitte einen Link veröffentlichen, auf dem das Problem verfolgt wird? – Drux

7

So habe ich alle ungültigen Übereinstimmungen entfernen können.

Ich überprüfte den Status des aktuellen Teilnehmers, wenn es eingeladen wird, rief ich ablehnenInviteWithCompletionHandler, sonst rief ich TeilnehmerQuitInTurnWithOutcome.

In beiden Completion-Blöcken habe ich dann removeWithCompletionHandler aufgerufen, um die Übereinstimmung zu entfernen.

Dies erzeugte ein paar Fehler, aber die Übereinstimmungen wurden noch entfernt, so dass meine Liste sauber ist.

Und hier ist ein Workaround, um zu vermeiden, in diesen Zustand zu beginnen. Dies hat den zusätzlichen Vorteil, dass der Eingeladene nicht einmal eine Benachrichtigung erhält, wenn der Inviter beendet wird, bevor er seinen ersten Zug beendet hat.

In playerQuitForMatch beenden Sie zuerst den Zug und dann im Completion-Handler, sofort die Übereinstimmung zu beenden. So,

[match endTurnWithNextParticipants:[NSArray arrayWithObject:nextParticipant] 
              turnTimeout:GKTurnTimeoutDefault 
              matchData:nil completionHandler:^(NSError *error) { 
               if (error) { 
                NSLog(@"%@", error); 
               } 

               [match participantQuitOutOfTurnWithOutcome:GKTurnBasedMatchOutcomeQuit 
                    withCompletionHandler:^(NSError *error) { 
                     if (error) { 
                      NSLog(@"%@" ,error); 
                     } 
                    }]; 
              }]; 
+0

Danke! Das hat für mich perfekt funktioniert! –

+0

Das! Vielen Dank, Muchas. – Binarian

5

Ich fand die Lösung. Verwenden Sie für ungültige Übereinstimmungen nur die Methode -participantQuitOutOfTurn und dann die Methode -removeWithCompletionHandler. Es wird komplett entfernt.

Verwandte Themen