Удаление GKTurnBasedMatch, которое находится в недопустимом состоянии

Я экспериментирую, чтобы попытаться узнать об GameKit, и я сделал простую игру и интерфейс, в котором перечислены мои игровые матчи. Я пытаюсь добавить возможность удаления игр с помощью метода removeWithCompletionHandler: в совпадении, но мне не удается удалить GKTurnBasedMatch, который, кажется, ввел недопустимое состояние.

Выбранная копия соответствующего матча:

$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)>
>

Кажется, что матч закончился. Тем не менее, у одного из участников есть результат: ни один, который я возглавляю документами, чтобы верить, недействителен для законченной игры. Попытка просто удалить игру дает:

Запрошенные операции не могут быть завершены, поскольку один или несколько параметров являются недопустимыми.

При попытке установить результаты и завершить игру дает:

Запрошенная операция не может быть выполнена, так как сеанс находится в недопустимом состоянии.

Я подумал, что, возможно, я не смог удалить игру, потому что локальный игрок является активным участником, но оба participantQuitInTurnWithOutcome:... и endTurnWithNextParticipants:... обе дают ошибку:

Запрошенная операция не может быть выполнена, так как сеанс находится в недопустимом состоянии.

. Я делаю что-то неправильно или я каким-то образом создаю неустранимую игру?

P.S. Я также не могу удалить игры через предоставленный интерфейс Game Center, где они перечислены в разделе "Игра поверх".

Ответы

Ответ 1

Вот как мне удалось удалить все недопустимые совпадения.

Я проверил статус текущего участника, если он был приглашен, я назвал declInviteWithCompletionHandler, иначе я вызвал участникаQuitInTurnWithOutcome.

В обоих блоках завершения я тогда вызвал removeWithCompletionHandler, чтобы удалить совпадение.

Это вызвало несколько ошибок, но совпадения все еще были удалены, поэтому мой список чист.

И вот обходное решение о том, как избежать перехода в это состояние для начала. Это имеет дополнительное преимущество, что приглашенный никогда не получает уведомления, если приглашающий уходит, прежде чем заканчивать свою первую очередь.

В playerQuitForMatch, сначала закончите поворот, а затем в обработчике завершения, немедленно прекратите матч. Таким образом,

[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);
                                                                         }
                                                                     }];
                                            }];

Ответ 2

К сожалению, я столкнулся с такой же ошибкой. Чтобы помочь другим понять проблему, в надежде исследовать решение, вы можете воссоздать это, пригласив друга на матч, но затем выходите из матча во время первого хода, прежде чем когда-либо подадите этот призыв к приглашенному игроку. Затем хостинг-плеер удаляет матч из Game Center. На приглашенном игровом устройстве у них будет соответствие, похожее на указанное выше, которое невозможно удалить. Я пробовал все виды обходных решений.

Мне еще не повезло, но я смогу обновить свой ответ решением, если найду его. В настоящее время я пытаюсь отправить игру в Game Center, и поэтому мне нужно найти способ обойти это. У меня будет заключение в течение следующего дня или двух.

UPDATE: Я просмотрел мои не удаляемые совпадения, и они почти такие же, как у вас, кроме того, что мой игрок с статусом Invited также имеет результат матча Won. Кажется, что ключом поставить совпадение в недопустимое состояние является то, что статус одного игрока будет Invited вместо Done, но статус соответствия должен быть завершен. Это общий элемент между нашими двумя случаями, и это крайний случай в коде Apple Game Center. Меня это не удивило бы, если бы они просто испортили этот крайный случай и ожидали, что вы "просто знаете", что вы не должны были помещать игроков в это состояние (несомненно, если вы внимательно прочтете их документы, вы сможете это вместе в конечном итоге).

Мое заключение заключается в том, что у Apple есть крайный кейс на руках, который остается незамеченным, потому что это может произойти, только если вы выйдете из нового матча, и только если вы пригласите друга, в двух случаях вы не можете часто тестировать. Кроме того, если вы неправильно устанавливаете результаты матча, я предполагаю, что этого никогда не произойдет, поэтому они просто не поймали его.

Поскольку я еще не отправлен, я собираюсь настроить приложение для определения совпадений в этом состоянии и игнорировать их. Я собираюсь сообщить консоли на кол-во, сколько совпадений находится в этом состоянии, так что я могу гарантировать, что он не будет развиваться после этого. Затем я собираюсь проанализировать свой код выхода и убедиться, что в этом краевом случае я просто никогда не могу снова добавить совпадение в это состояние. Я думаю, что, учитывая то, что мы знаем, мы должны проявлять инициативу и просто всасывать тот факт, что некоторые матчи проскальзывали.

Надеюсь, вы еще не отправили, поэтому совпадения с ошибками будут локализованы в среде Game Center Sandbox. Фактически, плохие совпадения просто локализованы для вашего тестового пользователя в Sandbox, поэтому вы можете просто выбросить этого пользователя и начать с нового пользователя после исправления вашей проблемы. Если вы выполните мои предыдущие предложения, вы должны подтвердить, что ваше приложение работает правильно, прежде чем делать этот шаг.

Если кто-то действительно найдет способ удалить эти совпадения ошибок, как только они будут существовать, сообщите нам об этом, но я надеюсь, что мои предложения и идентификация фактической причины будут достаточными, чтобы помочь вам приступить к реализации вашего проекта.

Ответ 3

Я нашел решение. Для недействительных совпадений просто используйте метод -participantQuitOutOfTurn, а затем -removeWithCompletionHandler. Он будет полностью удален.

Ответ 4

У меня похожая ситуация, если немного другая. Я начинаю матч, приглашаю вторую учетную запись для песочницы, а затем первый игрок уходит и удаляет игру до того, как второй игрок сможет ответить. Когда второй игрок пытается выйти из игры, они получают эту ошибку:

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.
}

Итак, насколько я могу судить, это происходит потому, что следующий участник для перемещения уже имеет статус "Готово", которое, как я предполагаю, связано с тем, что они уже ушли:

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

Надеюсь, это поможет другим диагностировать, если ничего другого. Хотелось бы услышать мнение других в отношении обходного решения или решения. Если это ошибка на части Apple, похоже, что это может стоить подать радар.

Ответ 5

Поддержка Apple Technical Developer подтвердила эту проблему. Представлен отчет об ошибке. Будет держать вас в курсе.