Как правильно выполнить аутентификацию GameCenter?

Я видел в сообщениях о переполнении стека, которые показывают фрагменты обработки аутентификации GameCenter. Тем не менее, ни одно из этих решений не решает ни одной из проблем, рассматриваемых в реальных случаях использования. А именно, [GKLocalPlayer localPlayer] .authenticateHandler - это просто обратный вызов состояния, и не более того. Он предоставляет контроллер представления, но существуют серьезные несоответствия в состояниях .authenticated и error.

Есть несколько вещей, которые я пытаюсь сделать: 1. Не открывать вход в игровой центр до тех пор, пока какая-либо функция не использует его. 2. Попробуйте выполнить автоматическую аутентификацию при запуске приложения. 3. Предоставьте пользователю некоторую информацию о том, почему функции GameCenter не работают. 4. Обеспечить механизм восстановления

А именно, если есть сообщение об ошибке, как я могу показать диалог входа?

Я получаю эту ошибку без viewController:

Случай 1:

Ошибка в GameCenterManager :: authenticateLocalPlayer [Интернет-соединение отключено.]

Несмотря на сообщение об ошибке, устройство полностью подключено к сети, так как safari прекрасно загружает cnn.com.

Случай 2:

Кто-то закрывает экран входа в систему, потому что он не готов, и в этом случае .authenticated возвращается как истина, viewController остается равным нулю, но все вызовы игрового центра не будут выполнены. Почему [GKLocalPlayer localPlayer] .authenticated имеет значение true, если это не так?

Случай 3:

Ошибка в GameCenterManager :: authenticateLocalPlayer [Операция не может быть завершена. (NSURLErrorDomain ошибка -1009.)]

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

Дело 4:

Ошибка в GameCenterManager :: authenticateLocalPlayer [Запрошенная операция была отменена или отключена пользователем.]

Это происходит, если пользователь отменяет viewController, который приложение было предложено представить Apple. Тем не менее, также нет восстановления или обнаружения этого состояния.

Дело 5:

Ошибка в GameCenterManager :: createMatch [Запрошенная операция не может быть завершена, поскольку локальный игрок не прошел аутентификацию.]

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

По сути, если GameCenter не просто работает тихо, что мы должны делать как дизайнеры приложений? Просматривать оповещения и сказать им, чтобы они вошли в систему с помощью приложения игрового центра и перезапустили приложение?

Вот мой код аутентификации:

//******************************************************
// Authenticate
//******************************************************
-(void)authenticateLocalPlayer:(bool)showLogin
{
    if( showLogin && self.loginScreen != nil )
    { [[WordlingsViewController instance] presentViewController:self.loginScreen animated:YES completion:nil]; }

    if( [GKLocalPlayer localPlayer].isAuthenticated )
    {
        NSDLog(NSDLOG_GAME_CENTER,@"GameCenterManager::authenticateLocalPlayer LocalPlayer authenticated");
    }
    __weak GameCenterManager* weakSelf = self;
    [GKLocalPlayer localPlayer].authenticateHandler = ^(UIViewController *viewController, NSError *error)
    {
        if (error != nil)
        {
            NSDLog(NSDLOG_GAME_CENTER,@"Error in GameCenterManager::authenticateLocalPlayer [%@]", [error localizedDescription]);
        }
        else
        {
            if (viewController != nil)
            {
                NSDLog(NSDLOG_GAME_CENTER,@"GameCenter: No authentication error, but we need to login");
                weakSelf.loginScreen = viewController;
            }
            else
            {
                if ( [GKLocalPlayer localPlayer].authenticated )
                {
                    NSDLog(NSDLOG_GAME_CENTER,@"GameCenter localPlayer authenticated");
                    weakSelf.gameCenterAvailable = YES;
                    weakSelf.localPlayer = [GKLocalPlayer localPlayer];
                    [weakSelf retrieveFriends];
                    [weakSelf loadPlayerPhoto:weakSelf.localPlayer];

                    for ( id<GameCenterDelegate> listener in weakSelf.listeners )
                    { [listener onPlayerAuthenticated]; }
                }
                else
                {
                    weakSelf.gameCenterAvailable = NO;
                }
            }
        }
    };
}

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

Ответы на вопрос(1)

Ваш ответ на вопрос