3G 连接的 GameKit 配对失败

GameKit matchmaking fails for 3G connections

我正在为 iOS 制作一款多人游戏,我在 Apple Developer Center 中阅读了 material,特别是 this one。这是我的自定义配对代码,非常简单:

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

        }
    }];  
}

但是,当一台或多台设备通过蜂窝网络连接到互联网时,配对会失败。当我调查潜在的错误时,我发现即使是 wifi 到 wifi 的情况,完成处理程序也不会按预期工作。也就是说,match.expectedPlayerCount 永远不会为 0。相反,当 - (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state 处理程序在完成处理程序之后被调用时游戏开始,如下所示:

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

现在的问题是,如果连接了 3g 设备(并且匹配)didChangeState,则永远不会调用。我在 Internet 和本网站上检查了其他几个相关问题,尽管它们远非令人满意。我还读到 Game Center 的沙盒服务器不可靠,并且对于某些人来说生产版本工作完美(它只是工作!)尽管沙盒模式存在错误,但我不想冒这个风险。有人在玩多人游戏时遇到过类似问题吗?

根据您向我们展示的代码,无论连接类型是 3G 还是其他方式,都不应该有任何问题;但是,如果您之前散布了与连接状态相关的异常处理代码,或者用于表示加载状态的图形,则某些东西可能会在逻辑上与其他地方相关联,并在游戏逻辑的此时产生此错误。即使是损坏的微调器图形也会成为一个问题。

您的代码中是否有任何其他异常处理程序调用了以下内容:

request.playersToInvite

request.playerGroup

那个改变了loader层的特性?

Hgeg,

您的代码没有任何问题。 您必须允许您的应用使用蜂窝数据,这需要用户许可。

以下段落选自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.

祝你好运

伊曼

根据苹果最新消息,从iOS9开始,沙盒模式将不再存在,取而代之的是一个统一的沙盒环境。

因此您将拥有一个可以共享相同帐户的统一环境,这应该可以解决沙盒模式中的所有常见问题。

新的统一系统还与 TestFlight 兼容,因此您将能够跨多个设备和帐户测试您的代码。

所有这些更改将由 apple 直接进行,因此唯一认为您可以做的就是等到他们更新到新系统,到目前为止,这是确保它不是沙盒的唯一方法问题。 欲了解更多信息,请在 WWDC video