1

所以我已经在这几个星期了,从来没有在网上的任何地方找到答案。源代码注释、各种文档和各种来源声称,ReceivedExchangeReplies(GKPlayer, GKTurnBasedExchangeReply[], GKTurnBasedExchange, GKTurnBasedMatch)当交换的所有接收者回复或超时时,应该调用该函数。应该为交换的发起者和 currentParticipant 调用它。

但是在我的应用程序中,它只会被调用为交换的发起者,而不是轮流持有者。我无法继续我的编码,因为当前的轮流持有者应该在完成交换后合并和解决交换。但它不能这样做,因为它永远不会收到有关交换完成的通知。

AuthenticationHandler工作正常,与问题无关:

func authenticateLocalPlayer() {
    let localPlayer: GKLocalPlayer = GKLocalPlayer.localPlayer()
    localPlayer.authenticateHandler = {(ViewController, error) -> Void in
        if((ViewController) != nil) {
            self.underlyingViewController.present(ViewController!, animated: true, completion: nil)
        } else if (localPlayer.isAuthenticated) {
            self.gamecenterEnabled = true
            localPlayer.unregisterAllListeners()
            localPlayer.register(self)
            self.findBattleMatch()
        } else {
            self.gamecenterEnabled = false
            print(error as Any)
        }
    }
}

以下是交换请求的发送方式:

currentMatch.sendExchange(to: [nextParticipant], data: GameState.encodeStruct(structToEncode: structToSend), localizableMessageKey: messageKey, arguments: ["X","Y"], timeout: TimeInterval(timeOutDebug), completionHandler: {(exchangeReq: GKTurnBasedExchange?,error: Error?) -> Void in
    if(error == nil ) {
        print("Operation successfull")
    } else {
        print(error as Any)
    }
})

被回复回复

exchange.reply(withLocalizableMessageKey: exchange.message! , arguments: ["XY","Y"], data: GameState.encodeStruct(structToEncode: exchangeReply), completionHandler: {(error: Error?) -> Void in
    if(error == nil ) {
        print("ExchangeReply sent successfully")
    } else {
        print(error as Any)
    }
})

完成交换之后,应自动调用以下覆盖函数。对于双方,对于交易所的发起者当前的持有者:

func player(_ player: GKPlayer, receivedExchangeReplies replies: [GKTurnBasedExchangeReply], forCompletedExchange exchange: GKTurnBasedExchange, for match: GKTurnBasedMatch){
    print("Exchange was completed, turnholder and Exchange-initiator should act on that in following code.")
    ...code...
}

这是上述 ObjectiveC 函数的 Swift 版本。

现在像所说的问题是,上面的函数只交换的发起者调用,而不是为当前的持有者调用(就像它应该是的那样)。当前的回合持有者希望将交易所所做的更改合并到游戏存档数据中。他没有得到应有的通知会留下一个问题和问题,因为他不能在没有得到通知的情况下采取行动。我可以通过另一个额外的交换手动通知他(这是我目前正在使用的解决方法),但这在某种程度上是题外话,因为他必须盲目地合并新的交换而不确定它是否已完成。

前 3 个步骤似乎工作得很好,因为我看到交换的发起者被通知了。唯一的问题是第四个函数没有像文档和教程中描述的那样被自动调用。

我最近的一个解释是,交换完成得太快了,而听众却没有意识到它曾经是活跃的(交换在收到后立即回复);但这只是一个疯狂的猜测。即使我想......无论我做什么来延迟回复交换(例如在交换上保存引用,DispatchQueue用于延迟的函数调用或类似的)都会导致交换结果为零或通信错误(消息是通过不同的代理错误发送)。

基本上,我想知道轮机持有人是否真的应该通过调用上述函数得到通知,或者它是否可能已被更改。

我真的很感谢这里的帮助,我已经在这工作了好几个星期了,还没有到任何地方。其他一切工作正常。我使用最新版本的 Swift 和使用 GKLocalPlayer 的最新方法,而不是直接实现侦听器(就像到处推荐的那样)。

亲切的问候, Skeltek

4

0 回答 0