GameKit配对无法实现3G连接

时间:2015-04-08 18:47:59

标签: ios objective-c gamekit

我正在为iOS制作多人游戏,我在Apple开发者中心阅读了这些材料,特别是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从不被调用。我在互联网和本网站上查了几个其他相关问题,虽然它们远非令人满意。我还读到Game Center的沙盒服务器不可靠,有些人的生产版本工作得很好(它只是工作!)尽管沙盒模式有错误,但我不想冒这个风险。有没有人在他们的多人游戏中遇到过类似的问题?

3 个答案:

答案 0 :(得分:2)

Hgeg,

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

以下段落选自Apple's support website

  

在Foundation层,您可以使用setAllowsCellularAccess:   NSMutableURLRequest上的方法,用于指定是否可以发送请求   通过蜂窝连接。您也可以使用allowsCellularAccess   检查当前值。

     

在Core Foundation层,您可以实现相同的目标   在打开之前设置kCFStreamPropertyNoCellular属性   从CFSocketStream或CFHTTPStream API获取的流。

     

在旧版iOS中,您可以继续使用   kSCNetworkReachabilityFlagsIsWWAN是一种尽力而为的确定方法   是否通过蜂窝连接发送流量,但是你   应该意识到它的局限性。

祝你好运

伊曼

答案 1 :(得分:1)

根据最新的苹果新闻,从iOS 9开始,沙箱模式将不再存在,而不是沙盒,您将拥有一个统一的环境。Unified envoiroment

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

新的统一系统它还与TestFlight兼容,因此您可以在多个设备和帐户中测试代码。

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

获取战利品

答案 2 :(得分:0)

根据您向我们展示的代码,无论连接类型,3G或其他方式,都应该是任何问题;但是,如果您之前散布的代码用于绑定到连接状态的异常处理,或者代表加载状态的图形,那么某些东西可能会在逻辑上与其他地方捆绑在一起并在游戏逻辑中产生此错误。即使腐败的微调图形也会成为一个问题。

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

$app->put('/updateUser', 'authenticate', function() use($app)
     {


        global $user_id;
        $isFileUpdated=false;
        $file_path = "../uploads/";

        if (isset ( $_FILES ['files'] ))
        {

            $file_path = $file_path . basename( $_FILES['files']['name']);
            if(move_uploaded_file($_FILES['files']['tmp_name'], $file_path))
            {
                $isFileUpdated=true;

            }
        }


        $name = $app->request->put ( 'name' );
        $email = $app->request->put ( 'email' );
        $phone=$app->request->put( 'phone' );
        $password = $app->request->put ( 'password' );
        $address=$app->request->put ( 'address' );
        $language=$app->request->put ( 'language' );
        $profession=$app->request->put ( 'profession' );

        $db = new DbHandler();
        $response = array();

        // updating task
        $result = $db->updateUser($user_id, $name, $email,$isFileUpdated,$file_path,$phone,$password,$address,$language,$profession);
        if ($result) 
        {
            // task updated successfully
            $response["error"] = false;
            $response["message"] = "User updated successfully";
        }
        else 
        {
            // task failed to update
            $response["error"] = true;
            $response["message"] = "User failed to update. Please try again!";
        }
        echoRespnse(200, $response);
    });

request.playersToInvite

改变了加载器层的特性?