【问题标题】:Why does Social.localUser.Authenticate lead to crash when there is no internet connection in Unity app?为什么在 Unity 应用程序中没有互联网连接时 Social.localUser.Authenticate 会导致崩溃?
【发布时间】:2016-02-27 20:18:00
【问题描述】:

有互联网连接

一切都完美无缺。没有导致崩溃的内存问题。

没有互联网连接

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

我的结论是问题出在下面这行代码

Social.localUser.Authenticate

当我注释掉上面的行时,没有互联网连接时内存问题就消失了。

这是我的相关代码

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

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

【问题讨论】:

  • 能否包含堆栈跟踪?
  • 好的,等一下,我现在就搞定。
  • 添加了它,但它只是一堆 applicationDidReceiveMemoryWarning()

标签: ios unity3d game-center unity5 unity3d-2dtools


【解决方案1】:

我的猜测是您最终需要与 Unity 交谈。当没有网络连接时,Game Center 将使用缓存的凭据来报告它已成功连接到服务器并经过身份验证,即使它没有。我有一个错误开放 - 并且正在与 Apple 讨论这个问题。此行为允许某些游戏类型即使在没有网络的情况下也能继续运行,然后在连接恢复时同步。但是,我遇到了一些问题,我认为我可以做一些事情,因为 GC 说它已经过身份验证,但我真的做不到,因为它真的不是。 :/

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

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

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

确认 Unity 可以彻底处理身份验证失败

  1. 建立连接

  2. 退出游戏中心

  3. 断开连接(飞行模式等)

  4. 重试您的应用

我希望 success 在这一点上是错误的并且运行干净。

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

编辑2:

我不得不回去查看我的代码,以确切了解我是如何强化它的。场景是:在完全断开连接和/或处于飞行模式时,Game Center 显示“欢迎回来”消息,并且 localPlayer.authenticated 设置为 YES...但是,错误代码已设置并抱怨它不能t 连接。

我打开了错误 22232706,“[GKLocalPlayer localPlayer].authenticated 在设置任何身份验证处理程序后总是返回 true”,并且仍在进行中的讨论。 Apple 确认了这一行为,但表示其意图。

以下是我如何强化身份验证处理程序来处理这种情况。由于 Unity 正在为您处理此问题,因此对您没有帮助,但我认为其他读者可能会觉得这很有帮助。 (TL;DR 版本是:总是 always always 先检查错误代码,然后再检查 .authenticated 或检查是否设置了 viewController

[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 制作的游戏数量众多,我不知道为什么很难找到有关此问题的文档。我确定添加 Game Center 真的很常见:S
  • @Joe:谢谢,这是一个非常痛苦的练习。我花了几天时间才最终缩小模式:一旦登录,您总是报告为已通过身份验证,即使后续登录未连接。互联网上绝大多数身份验证处理程序示例都容易受到这种情况的影响。
  • @Jess:这听起来和我遇到的场景一模一样。你死在 re: 文档上。 Apple 的 GC 文档都被标记为“初步的”(几年来),含糊不清,缺少许多关键细节,并且(在某些情况下)完全错误。 :(
  • 感谢您的信息。我想现在我知道它为什么会发生,但不知道如何在我的代码中证明它的合理性:S
猜你喜欢
  • 2016-06-09
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多