你如何 "resolve" GKTurnBasedExchange?

How do you "resolve" a GKTurnBasedExchange?

我正在使用 GKTurnBasedExchange 以一种方式发送数据。当某些触发器发生时,它会通知其他玩家。然而,当时其他玩家甚至可能不在游戏中。轮流有 48 小时的超时,所以理论上,如果玩家 1 发送所述交换,玩家 3 可能几天都不会接收它。没关系,玩家 1 不需要或期望任何响应。

但是,当 player1 尝试保存比赛数据、结束回合或退出比赛时,出现错误:

Error Domain=GKErrorDomain Code=3 "The requested operation could not be completed due to an error communicating with the server." UserInfo=0x19317970 {GKServerStatusCode=5134, NSUnderlyingError=0x16f15db0 "The operation couldn’t be completed. status = 5134, Invalid operation for this session because the exchange was not resolved. All exchanges must be resolved before the current player can complete this operation.

好吧,除了一个小细节外,加粗的文字似乎很容易解释:我在任何地方都找不到任何关于什么构成 "resolved" 交换的参考。我不希望回复此消息。即使我这样做了,也可能需要几天时间才能收到。我能看到的唯一选择是发送方取消交换,这违背了发送交换的初衷

那么,究竟如何完成一笔交易呢?什么一系列的步骤,除了取消兑换,让游戏中心满意兑换已经"resolved?" 我正在使用:

    [theMatch sendExchangeToParticipants:exchangeParticipants
                                    data:exchangeData
                   localizableMessageKey:@"F1"
                               arguments:nil
                                 timeout:600
                       completionHandler:^(GKTurnBasedExchange *exchange, NSError *error)
                       {
                           if (error)
                           {
                               VLOG(LOWLOG, @"%@", [error description]);
                           }
                       }
    ];

其次是:

[theMatch saveCurrentTurnWithMatchData:dataCopy completionHandler:^(NSError *error)
 {
     if (error)
     {
         VLOG(LOWLOG, @"%@", [error description])
     }
 }];

saveCurrentTurnWithMatchData 调用returns 上述错误。

谢谢!

嗯,原来兑换不能用。 Game Kit 的另一个限制。对于遇到此线程的任何人,我发现 WWDC 2013 会话 506 说:

  1. 所有参与者都必须响应游戏中心才能将交换标记为"completed"
  2. 您必须致电:

    [match saveMergedMatchData:dataCopy
         withResolvedExchanges:match.completedExchanges
             completionHandler:...];
    

因此,您不能使用交换器进行单向通信。必须有响应(或等待超时)。

我想我会回答以下未提出的问题:如何使用通知发送单向通信。

我认为最好的 API 是 GKTurnBasedMatch 实例上的 setLocalizableMessageWithKey(key:arguments:) 或 sendReminderToParticipants(localizableMessageKey:arguments:completionHandler:)。

我想我明白了。 伙计,伙计这是理解 Apple 文档的一个口号。

最后我其实也没看懂:这是蛮力试错的结果

事情是这样的:你可以用交易所做很多事情,但要真正解决它们,你必须调用:

saveMergedMatch(matchData: Data, withResolvedExchanges: [GKTurnBasedExchange], completionHandler: ((Error?) -> Void))

虽然有几个问题。

  • 只有本场比赛的currentParticipant(轮到的玩家)才能调用saveMergedMatch成功。
  • 它只适用于不处于 .active 状态的交易所。
  • 据我所知,只有两种方法可以通过编程方式从 .active 状态中获取交换。
  • 更难的方法:交换的所有接收者都必须对交换采取行动——这本身就是一个模糊的过程,对此无能为力。如果所有收件人都做出回应,Game Center 本身将处理更改交换状态,我认为。不过不确定,因为我不这样做。 [这里我唯一能给的帮助是,如果你在发送的时候给交换一个很短的超时时间,超时后Game Center会自动调整交换的状态,你的接收者不需要做任何事情。]
  • 不太简单的方法:发送者并且只有交换的发送者可以通过调用交换的方法cancel(withLocalizableMessageKey key: String, arguments: [String], completionHandler: ((Error?) -> Void)? = nil)来取消它。这种方式的优点是 不必轮到发件人 来取消它。这是当前轮到者无关紧要的少数情况之一。不幸的是,这也有一个问题:如果有人已经回复,则无法取消交换。

所以结果是无法保证任何单个玩家都能解决交换,原因有两个:

  1. active exchanges 移动到 completed exchanges 的过程只能以编程方式访问以取消交换,并且只能由发起它的玩家,并且只有在没有人回应的情况下。
  2. 已完成交换变为已解决交换的实际过程只能由比赛中的玩家触发currentParticipant 属性.

就我个人而言,我可以使用它,现在我理解了它(我希望),但毫无疑问这很痛苦。