¿Cuál es la forma correcta de hacer la autenticación de GameCenter?

He visto en publicaciones sobre desbordamiento de pila que muestran fragmentos de manejo de autenticación de GameCenter. Sin embargo, ninguna de estas soluciones aborda ninguno de los problemas que cubren los casos de uso del mundo real. A saber, el [GKLocalPlayer localPlayer] .authenticateHandler es solo una devolución de llamada del estado, y no mucho más. Proporciona un controlador de vista, pero hay inconsistencias masivas en los estados autenticados y de error.

Intento hacer algunas cosas: 1. No abrir el inicio de sesión del centro de juegos hasta que una función lo use 2. Intentar autenticar en silencio al iniciar la aplicación 3. Proporcionar información al usuario por qué las funciones de GameCenter no funcionan 4. Proporcionar un mecanismo de recuperación.

Es decir, si hay un error informado, ¿cómo puedo mostrar el diálogo de inicio de sesión de todos modos?

Me sale este error sin viewController:

Caso 1:

Error en GameCenterManager :: authenticateLocalPlayer [La conexión a Internet parece estar fuera de línea]

A pesar de su mensaje de error, el dispositivo está completamente en línea, ya que safari carga cnn.com muy bien.

Caso 2:

Alguien cierra la pantalla de inicio de sesión porque no está listo, en cuyo caso .authenticated vuelve a ser cierto, viewController permanece en cero, pero todas las llamadas al centro de juegos fallarán. ¿Por qué el [GKLocalPlayer localPlayer] .authenticated se establece en verdadero cuando no lo es?

Caso 3:

Error en GameCenterManager :: authenticateLocalPlayer [La operación no se pudo completar. (NSURLErrorDomain error -1009.)]

Esto sigue ocurriendo pero no hay nada que la aplicación pueda hacer por el usuario. En este caso, ¿cuál debería ser el mensaje? ¿Cambiar aplicaciones a Game Center e iniciar sesión allí?

Caso 4:

Error en GameCenterManager :: authenticateLocalPlayer [El usuario ha cancelado o deshabilitado la operación solicitada]

Esto sucede si el usuario cancela el viewController que Apple le dijo a la aplicación que presentara. Sin embargo, tampoco hay recuperación o detección de este estado.

Caso 5:

Error en GameCenterManager :: createMatch [La operación solicitada no se pudo completar porque el reproductor local no se ha autenticado.]

Esto sucede si el usuario inició sesión, pero por cualquier motivo cierra la sesión de GameCenter y luego vuelve a la aplicación. Se le informará a la aplicación que el usuario todavía está autenticado cuando claramente no lo está, pero no hay llamadas que pueda hacer para que aparezca otro inicio de sesión.

Entonces, esencialmente, si GameCenter no solo funciona en silencio, ¿qué debemos hacer como diseñadores de aplicaciones? ¿Ver alertas y decirles que inicien sesión con la aplicación del centro de juegos y reinicien la aplicación?

Aquí está mi código de autenticación:

//******************************************************
// 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;
                }
            }
        }
    };
}

Esta función se llama dos veces: una al inicio de la aplicación para crear un estado de inicio de sesión válido, y la segunda si el usuario no está autenticado y trata de usar una función de la aplicación que requiere un centro de juegos. En esta aplicación, está creando una partida por turnos o viendo amigos

Respuestas a la pregunta(1)

Su respuesta a la pregunta