2015-04-08 17 views
35

Tworzę grę dla wielu graczy na iOS i czytam materiał w Apple Developer Center, a konkretnie pod numerem this one. Tu jest mój kodu niestandardowego kojarzeń, który jest dość prosta:Gra kojarzeń GameKit kończy się niepowodzeniem w przypadku połączeń 3G

- (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]; 
      } 

     } 
    }]; 
} 

Jednak nie swatanie gdy jedno lub więcej urządzeń są podłączone do Internetu za pośrednictwem sieci komórkowych. Kiedy zbadałem podstawowy błąd, dowiedziałem się, że nawet jeśli jest to wifi do wifi, obsługa zakończenia nie działa zgodnie z przeznaczeniem. Oznacza to, że match.expectedPlayerCount nigdy 0. Zamiast tego, gra rozpoczyna się, gdy - (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state obsługi jest wywoływana po obsługi zakończenia następująco:

... 
- (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; 
... 

Problem teraz jest, jeśli urządzenie jest połączone z 3G (i dopasowane-sort of) didChangeState nigdy nie jest wywoływana. Sprawdziłem kilka innych powiązanych pytań w Internecie i na tej stronie, chociaż są one dalekie od zadowalających. Czytałem również, że serwery Sandbox Game Center nie są niezawodne i dla niektórych osób wersja produkcyjna działała idealnie (po prostu działa!) Pomimo błędów w trybie piaskownicy, ale nie chcę podejmować tego ryzyka. Czy ktoś miał podobny problem z grą wieloosobową?

+1

Wystarczy szybki wgląd. Czy twój serwer jest otwarty przez Internet, czy pracujesz w sieci LAN? Domyślam się, że to pierwszy, ale jeśli ktoś zapłacił mi pensa za każdym razem, gdy miałem takie proste problemy z infrastrukturą, nie zauważając, byłbym już dość bogaty :) Jeśli nie jest otwarty w całym Internecie, powinieneś przełożyć swoje urządzenie VPN – Bartserk

+0

Tak więc, aby było jasne, mówisz, że jeśli urządzenie łączy się z meczem za pomocą 3g didChangeState nigdy nie jest wywoływane? Ponieważ powinien być wywoływany za każdym razem, gdy nowy gracz łączy się z meczem. To tam powinieneś sprawdzić oczekiwaną liczbę graczy na 0. –

Odpowiedz

2

Hgeg,

Nie ma nic złego w tym kodzie. Musisz zezwolić komórkowej transmisji danych na swoją aplikację, która wymaga pozwolenia użytkowników.

dodaje się ustęp wybrany spośród Apple's support website:

At the Foundation layer, you can use the setAllowsCellularAccess: method on NSMutableURLRequest to specify whether a request can be sent over a cellular connection. You can also use the allowsCellularAccess to check the current value.

At the Core Foundation layer, you can achieve the same thing by setting the kCFStreamPropertyNoCellular property before opening a stream obtained from the CFSocketStream or CFHTTPStream APIs.

In older versions of iOS, you can continue to use the kSCNetworkReachabilityFlagsIsWWAN as a best-effort way of determining whether traffic will be sent over a cellular connection, but you should be aware of its limitations.

Powodzenia

Iman

0

Na podstawie kodu, który nam pokazałeś, nie powinno być żadnych problemów bez względu na rodzaj połączenia, 3G lub w inny sposób; Jeśli jednak poprzednio był to kod przerywany do obsługi wyjątków, który był przywiązany do stanu połączenia, lub do grafiki, która reprezentuje stan ładowania, coś można logicznie powiązać gdzie indziej i wygenerować ten błąd w tym momencie logiki gry. Nawet uszkodzona grafika spinner może stać się problemem.

Czy masz jakieś inne programy obsługi wyjątków w kodzie, który wywołał następujący:

request.playersToInvite 

lub

request.playerGroup 

lub

który zmienił charakterystykę warstwy ładowarka?

+0

Byłbyś także zainteresowany jakimkolwiek innym kodem, o który się martwisz, gdy masz otwartą nagrodę. – miniscule

+0

Pokaż nam dowolny kod, który bezpośrednio manipuluje preferencjami centrum gier, przywraca asynchroniczne do głównej kolejki bez weryfikacji stanu lub ma włączoną autouzupełnianie (zawsze wydaje się być drażliwy). Czy zauważyłeś jakieś różnice między wersjami iOS przez przypadek? Polecam również napisanie procedury obsługi zaproszeń i wprowadzenie rejestrowania, dzięki czemu robisz więcej niż powiadomienia w ramach procedur. Wiem, że to może być uciążliwe, ale zdecydowanie zgadzam się z twoim oświadczeniem na temat ryzyka związanego z wydaniem. – miniscule

+0

Przed czymkolwiek, wstaw NSLog (@ "ERROR: Error makeMatch:% @", [opis błędu]); gdzie znajduje się błąd i daj nam znać o wynikach. Być może warto rozważyć zmianę na bardziej zaangażowany model zapraszania, aby uzyskać większą elastyczność. Tak, zwiększysz złożoność, ale im więcej czasu poświęcisz na poprawienie łączności gracza (i komunikatów o stanie), tym lepsze będzie twoje długoterminowe wsparcie. – miniscule

1

Według najnowszych wiadomości z jabłek, z iOS 9, tryb piaskownica nie będzie już istnieć, zamiast piaskownicy będziesz mieć jedno zunifikowane środowisko. Unified envoiroment

Dzięki temu masz tylko jedno ujednolicone środowisko, w którym możesz udostępniać te same konta, co powinno rozwiązać wszystkie typowe problemy z trybu SandBox.

Nowy system zunifikowany jest również kompatybilny z TestFlight, dzięki czemu można przetestować kod na wielu urządzeniach i kontach.

Wszystkie te zmiany zostaną wprowadzone bezpośrednio przez Apple, więc jedyne, co możesz zrobić, to poczekać, aż zaktualizują się do nowego systemu, do tej pory jest to jedyny sposób, aby upewnić się, że nie jest to problem z piaskownicą . Aby uzyskać więcej informacji, należy uzyskać łup w WWDC video

Powiązane problemy