ios objective-c gamekit

ios - GameKit Matchmaking falla para conexiones 3G



objective-c (3)

Estoy haciendo un juego multijugador para iOS y leo el material en el Apple Developer Center, específicamente este . Aquí está mi código para hacer emparejamientos personalizados, que es bastante sencillo:

- (void)findProgrammaticMatch { GKMatchRequest *request = [[GKMatchRequest alloc] init]; request.minPlayers = 2; request.maxPlayers = 2; request.defaultNumberOfPlayers = 2; request.playersToInvite = nil; request.playerAttributes = 0; request.playerGroup = 0; UILabel *loading = (UILabel *)[aiw viewWithTag:792]; [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error) { if (error){ //error handling [loaderLayer stopAnimating]; UIButton *cancelButton = (UIButton *)[loaderLayer viewWithTag:442]; [cancelButton setTitle:@"Go Back" forState:UIControlStateNormal]; loading.text = @"Cannot find any players. Please try again later."; } else if (match != nil) { //save match self.match = match; self.match.delegate = self; loading.text = @"Found a player. Preparing session..."; if (!self.matchStarted && match.expectedPlayerCount == 0) { self.matchStarted = YES; //begin game logic [self.scene setState:1]; self.myTicket = 1000+arc4random_uniform(999); [self.scene send:self.myTicket]; [self stopLoading]; } } }]; }

Sin embargo, el emparejamiento falla cuando uno o más dispositivos están conectados a Internet a través de redes celulares. Cuando investigué el error subyacente, descubrí que incluso si se trata de un wifi a wifi, el controlador de finalización no funciona como se esperaba. Es decir, match.expectedPlayerCount nunca es 0. En su lugar, el juego comienza cuando - (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state controlador de - (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state se invoca después del controlador de finalización de la siguiente manera:

... - (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state { switch (state) { case GKPlayerStateConnected: self.matchStarted = YES; //begin game logic [self.scene setState:1]; self.myTicket = 1000+arc4random_uniform(999); [self.scene send:self.myTicket]; [self stopLoading]; break; ...

El problema ahora es si un dispositivo con 3g está conectado (y emparejado-tipo de) didChangeState nunca se invoca. Revisé otras preguntas relacionadas en Internet y en este sitio, aunque están lejos de ser satisfactorias. También leí que los servidores de sandbox de Game Center no son confiables y para algunas personas la versión de producción funcionó perfectamente (¡simplemente funciona!) A pesar de los errores en el modo de espacio aislado, pero no quiero correr ese riesgo. ¿Alguien ha experimentado un problema similar con su juego multijugador?


De acuerdo con las últimas noticias de Apple, desde iOS 9, el modo de caja de arena ya no existirá, en lugar de la caja de arena tendrá un entorno unificado.

Por lo tanto, solo tendrá un entorno unificado donde podrá compartir las mismas cuentas, esto debería resolver todos los problemas habituales del modo SandBox.

El nuevo sistema unificado también es compatible con TestFlight, por lo que podrá probar el código en múltiples dispositivos y cuentas.

Todos estos cambios se realizarán directamente por Apple, por lo que lo único que puede hacer es esperar hasta que se actualicen al nuevo sistema, hasta ahora es la única manera de asegurarse de que no se trate de un problema de Sand Box. Para obtener más información, saque un botín en el video WWDC


En función del código que nos ha mostrado, no debe haber ningún problema, independientemente del tipo de conexión, 3G o de otro tipo; sin embargo, si previamente intercalaste el código para el manejo de excepciones que estaba vinculado al estado de conexión, o para gráficos que representan un estado de carga, algo podría estar vinculado lógicamente en otro lugar y producir este error en este punto de la lógica del juego. Incluso un gráfico de spinner corrupto puede convertirse en un problema.

¿Tuvo algún otro manejador de excepciones en el código que llamó a lo siguiente?

request.playersToInvite

o

request.playerGroup

o

que cambió la característica de la capa de carga?


Hgeg,

No hay nada malo con tu código. Debe permitir el uso de datos móviles a su aplicación que necesita permiso de los usuarios.

El siguiente párrafo se selecciona del sitio web de soporte de Apple :

En la capa Foundation, puede usar el método setAllowsCellularAccess: en NSMutableURLRequest para especificar si se puede enviar una solicitud a través de una conexión celular. También puede usar allowCellularAccess para verificar el valor actual.

En la capa Fundación básica, puede lograr lo mismo configurando la propiedad kCFStreamPropertyNoCellular antes de abrir una secuencia obtenida de las API CFSocketStream o CFHTTPStream.

En versiones anteriores de iOS, puede continuar utilizando kSCNetworkReachabilityFlagsIsWWAN como una forma de mejor esfuerzo para determinar si el tráfico se enviará a través de una conexión celular, pero debe tener en cuenta sus limitaciones.

Buena suerte

Iman