当Unity应用程序中没有互联网连接时,为什么Social.localUser.Authenticate导致崩溃? [英] Why does Social.localUser.Authenticate lead to crash when there is no internet connection in Unity app?

查看:493
本文介绍了当Unity应用程序中没有互联网连接时,为什么Social.localUser.Authenticate导致崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具有互联网连接

一切正常.没有导致崩溃的内存问题.

Everything works flawlessly. There is no memory problem leading to crash.

没有互联网连接

该应用程序进入菜单屏幕,最终由于内存不足而崩溃.

The app proceeds to the menu screen, where it eventually crashes because it is out of memory.

我已经得出结论,问题出在以下代码行

Social.localUser.Authenticate

当我在上一行中注释时,没有互联网连接时,内存问题就消失了.

When I comment out the above line, the memory problem goes away when there is no internet connection.

这是我的相关代码

void Start () 
{
    Social.localUser.Authenticate(ProcessAuthentication);
}

public void ProcessAuthentication(bool success) 
{
    if(success)
        Debug.Log ("Authenticated");
    else
        Debug.Log ("Failed to authenticate");
}

领先于崩溃

2016-02-27 15:46:37.131 BrickBall[449:60670] Received memory warning.
WARNING -> applicationDidReceiveMemoryWarning()
2016-02-27 15:46:37.302 BrickBall[449:60670] Received memory warning.
WARNING -> applicationDidReceiveMemoryWarning()
2016-02-27 15:46:37.349 BrickBall[449:60670] Received memory warning.
WARNING -> applicationDidReceiveMemoryWarning()
2016-02-27 15:46:37.437 BrickBall[449:60670] Received memory warning.
WARNING -> applicationDidReceiveMemoryWarning()
Message from debugger: Terminated due to memory issue

当没有Internet连接时,为什么那行代码会导致内存不足崩溃?

Why would that line of code be causing the out of memory crash when there is no internet connect?

推荐答案

我的猜测是,您最终将需要与Unity交流.当没有网络连接时,Game Center将使用缓存的凭据来报告它已成功连接到服务器并进行了身份验证,即使没有成功.我有一个与苹果有关的bug以及正在进行的讨论.此行为使某些游戏类型即使在没有网络的情况下也可以继续,然后在恢复连接后稍后同步.但是,我遇到了一些问题,我以为我可以做些事情,因为GC表示它已通过身份验证,但我真的做不到,因为它不是经过验证的. :/

My guess is that you'll eventually need to talk to Unity. Game center will use cached credentials when there's no network connectivity to report that it successfully connected to the server and authenticated, even though it didn't. I have a bug open--and an ongoing discussion--with Apple on this. This behavior allows some game types to continue even when there's no network, then sync up later when connection is restored. However, I ran into problems where I assumed I could do things because GC said it was authenticated, but I really couldn't because it really wasn't. :/

这意味着应用程序必须处理三种情况:

This means apps have to handle three cases:

  • 使用GC成功进行身份验证
  • 使用GC的身份验证失败
  • 身份验证失败,但根据缓存的数据报告为成功

Unity可能无法处理第三种情况.要确认或反驳,请尝试以下操作:

It's possible that Unity doesn't handle the third situation. To confirm or refute this, try the following:

确认Unity确实处理了身份验证失败

  1. 建立连接

  1. establish connectivity

退出游戏中心

中断连接(飞机模式等)

Break connectivity (airplane mode, etc)

重试您的应用

我希望success在这一点上是错误的,并且运行得井井有条.

I would expect that success would be false at this point and run cleanly.

如果这能按预期工作,我将与Unity讨论他们如何处理Game Center,以在断开连接的情况下报告(缓存的)成功.

If that works as expected, I'd talk to Unity about how they handle Game Center reporting a (cached) success in a disconnected situation.

我不得不回头看一下我的代码,以确切地了解我如何对付它.情况是:在完全断开连接和/或处于飞行模式时,Game Center会显示欢迎回来"消息,并且localPlayer.authenticated设置为YES ...但是,错误代码已设置并抱怨说它无法执行"t连接.

I had to go back and look at my code to see exactly how I hardened against it. The scenario was: while completely disconnected and/or in airplane mode, Game Center was presenting the "welcome back" message and localPlayer.authenticated was set to YES... BUT, the error code was set and complaining that it couldn't connect.

我打开了错误22232706,"[GKLocalPlayer localPlayer] .authenticated在设置了任何身份验证处理程序后始终返回true",并且该讨论仍在进行中.苹果确认了该行为,但表示其意图.

I opened bug 22232706, "[GKLocalPlayer localPlayer].authenticated always returns true after any authentication handler is set," and which still has an ongoing discussion. Apple confirmed the behavior, but says its intended.

下面是我如何加强身份验证处理程序以应对这种情况.由于Unity正在为您处理此问题,因此它对您无济于事,但我认为其他读者可能会觉得有帮助. (TL; DR版本是:总是总是 总是,在检查.authenticated之前或在检查viewController是否已设置之前,先检查错误代码)

Below is how I hardened my authentication handler to deal with this situation. It won't help you since Unity is handling this for you, but I thought other readers may find this helpful. (The TL;DR version is: always always always check the error code first, before you check .authenticated or before you check if viewController is set)

[localPlayer setAuthenticateHandler:^(UIViewController *loginViewController, NSError *error)
 {
    //Note: this handler fires once when you call setAuthenticated, and again when the user completes the login screen (if necessary)

     //did we get an error? Could be the result of either the initial call, or the result of the login attempt
     //Very important: ALWAYS check `error` before checking for a viewController or .authenticated.
     if (error)
     {
         //Here's a fun fact... even if you're in airplane mode and can't communicate to the server,
         //when this call back fires with an error code, localPlayer.authenticated is sometimes set to YES despite the total failure. ><
         //combos seen so far:
         //error.code == -1009 -> authenticated = YES
         //error.code == 2 -> authenticated = NO
         //error.code ==3 -> authenticated = YES

         if ([GKLocalPlayer localPlayer].authenticated == YES)
         {
             NSLog(@"error.code = %ld but localPlayer.authenticated = %d", (long)error.code, [GKLocalPlayer localPlayer].authenticated);
         }

         //Do stuff here to disable network play, disable buttons, warn users, etc.
         return;
     }

     //if we received a loginViewContoller, then the user needs to log in.
     if (loginViewController)
     {
         //the user isn't logged in, so show the login screen.
         [rootVC2 presentViewController:loginViewController animated:NO completion:^
          {

              //was the login successful?
              if ([GKLocalPlayer localPlayer].authenticated)
              {
                    //enable network play, or refresh matches or whatever you need to do...
              }
          }];
     }

     //if there was not loginViewController and no error, then the user is alreay logged in
     else
     {
         //the user is already logged in
         //refresh matches, leaderboards, whatever you need to do...
     }

 }];

这篇关于当Unity应用程序中没有互联网连接时,为什么Social.localUser.Authenticate导致崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆