GameKit:与插件的连接在使用中中断



我已经试着解决这个问题好几个星期了。苹果开发者论坛上没有回应。苹果开发者技术支持没有真正的帮助。考虑到这个问题在我的项目中发生的可能性很高,我不敢相信它没有得到任何人的解决。无论如何,这是我的GameKitManager类:

final class GameCenterManager : NSObject, GKLocalPlayerListener {

static let manager = GameCenterManager()
weak var delegate: GameCenterManagerDelegate?
var gameCenterViewController: UIViewController?
var match: GKMatch?
static var isAuthenticated: Bool {
return GKLocalPlayer.local.isAuthenticated
}
var matchmakerViewController: GKMatchmakerViewController?
var invite: GKInvite?


override init() {
super.init()
}
func authenticatePlayer() {
GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in

self.delegate?.didChangeAuthStatus(isAuthenticated: GKLocalPlayer.local.isAuthenticated)
if GKLocalPlayer.local.isAuthenticated {
GKLocalPlayer.local.register(self)
}
// If the User needs to sign to the Game Center
else if let vc = gcAuthVC {
self.delegate?.presentGameCenterAuth(viewController: vc)
}
else {
print(">>>>> Error authenticating the Player! (error?.localizedDescription ?? "none") <<<<<")
}
}
}

func presentMatchmaker() {
guard GKLocalPlayer.local.isAuthenticated else { return }

let request = GKMatchRequest()
request.minPlayers = 2
request.maxPlayers = 4
request.inviteMessage = "Would you like to play?"

matchmakerViewController = GKMatchmakerViewController(matchRequest: request)
matchmakerViewController!.matchmakerDelegate = self
delegate?.presentMatchmaking(viewController: matchmakerViewController)
}


func player(_ player: GKPlayer, didAccept invite: GKInvite) {
self.invite = invite
// Start match making 4 seconds after to let the invitation sliding menu to finish loading
let seconds = 4.0
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
self.makeMatchmakerVC(from: invite)
}
}


func makeMatchmakerVC(from invite:GKInvite) {
// Accepting invitation from GKMatchmakerViewController (Friends are displayed)
if matchmakerViewController != nil {
matchmakerViewController!.dismiss(animated: true, completion: {
self.matchmakerViewController = GKMatchmakerViewController(invite: invite)
self.matchmakerViewController!.matchmakerDelegate = self
self.delegate?.presentMatchmaking(viewController: self.matchmakerViewController!)
})
}
// Accepting invitation when GKMatchmakerViewController is not yet presented
else {
guard let vc = GKMatchmakerViewController(invite: invite) else { return }
self.matchmakerViewController = vc
matchmakerViewController!.matchmakerDelegate = self
delegate?.presentMatchmaking(viewController: matchmakerViewController!)
}
}
}

extension GameCenterManager: GKMatchmakerViewControllerDelegate {

func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFind match: GKMatch) {

print("-----matchmakerVC did find match-------")

viewController.dismiss(animated: true, completion: {
self.match = match
self.match!.delegate = self
self.delegate?.presentGame(match: self.match!)
})
}

func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) {
viewController.dismiss(animated: true)
delegate?.matchmakingCancelled()
}

func matchmakerViewController(_ viewController: GKMatchmakerViewController,
didFailWithError error: Error)
{

viewController.dismiss(animated: true, completion: {
print("################# fail with error ##################n(error.localizedDescription)n")
self.matchmakerViewController!.matchmakerDelegate = nil
self.matchmakerViewController = nil
self.invite = nil
self.match = nil
})
}
}

这就是如何复制问题。

  • 玩家启动应用程序。两者都会看到简介屏幕。

  • 播放器1点击";在GameCenter中玩";。Matchmaker VC现在对玩家1开放。

  • 玩家1将玩家2添加到游戏中,然后点击"邀请"one_answers"开始"按钮。

  • 播放器2收到邀请(从顶部滑动消息),并立即点击它以接受邀请(不要等待邀请来完成乐曲播放)。请注意,播放器2仍处于简介场景中。

  • 玩家2收到连接错误,即使他/她接受了邀请,而玩家1被通知玩家2加入了游戏并进入游戏场景。

  • 就代码流而言,播放器2调用方法"播放器(播放器:邀请:)";根据邀请创建新的matterViewController并呈现;完成后,播放器2收到以下错误:

    -----玩家--确实接受了邀请-------玩家2

    INTROSCENE:代理演示_正在制作呼叫。。。。。。

    2020-11-08 17:03:07.083450-0500 igkTest[4868:2788074][生命周期][u 196C65DD-6BC1-46D7-B43D-1399E5802378:m(null)][com.apple.GameCenterUI.GameCenterMatchmakerExtension(1.0)]使用时插件连接中断。

    2020-11-08 17:03:07.083680-0500 igkTest[4868:2788073][生命周期][u 196C65DD-6BC1-46D7-B43D-1399E5802378:m(null)][com.apple.GameCenterUI.GameCenterMatchmakerExtension(1.0)]使用时插件的连接无效。

    2020-11-08 17:03:07.160824-0500 igkTest[48868:2788043][Match]无法设置玩家的连接状态:(玩家ID:G:271575631,别名:玩家),因为尚未设置邀请电报。当我们稍后设置inviteDelegate并调用sendQueuedStatesAndPackets时,状态可能会直接更改为Ready。

    2020-11-08 17:03:07.166467-0500 igkTest[48868:2788074][断言]获取断言时出错:<错误域=RBSAssertionErrorDomain代码=2";指定的目标进程不存在";UserInfo={NSLocalizedFailureReason=指定的目标进程不存在}>

    2020-11-08 17:03:07.1169507-0500 igkTest[48868:2788074][断言]获取断言时出错:<错误域=RBSAssertionErrorDomain代码=2";指定的目标进程不存在";UserInfo={NSLocalizedFailureReason=指定的目标进程不存在}>

    2020-11-08 17:03:07.170369-0500 igkTest[48868:2788070][断言]获取断言时出错:<错误域=RBSAssertionErrorDomain代码=2";指定的目标进程不存在";UserInfo={NSLocalizedFailureReason=指定的目标进程不存在}>

    2020-11-08 17:03:07.175163-0500 igkTest[4868:2788043][Error]扩展请求因错误而中断:错误域=扩展错误域代码=-5900";(null)";

    2020-11-08 17:03:07.218324-0500 igkTest[4868:2788043]viewServiceDidTerminateWithError::Error Domain=_UIViewServiceInterfaceErrorDomain Code=3〃;(null)";UserInfo={Message=服务连接中断}

    2020-11-08 17:03:07.652617-0500 igkTest[4868:2788043][ViceroyTrace][错误]VCCTServiceMonitor_GetDataIndicator状态:193设备没有蜂窝基带

    2020-11-08 17:03:07.944964-0500 igkTest[48868:2788203][ViceroyTrace][ERROR]OSPFParse_ParsePacketHeader:1083错误目的地计数=0

    2020-11-08 17:03:07.946241-0500 igkTest[4868:2788203][ViceroyTrace][ERROR]OSPFParse_ParsePacketHeader:1100校验和=42500与不匹配

    2020-11-08 17:03:07.965383-0500 igkTest[4868:2788223][ViceroyTrace][ERROR]gckSessionCheckPendingConnections:1454 gckSessionCheck PendingConnections:iICEChecksLeft=0,iUnconnectedNodeCount=0,iDDsExpected=1

    2020-11-08 17:03:07.966116-0500 igkTest[4868:2788223][ViceroyTrace][ERROR]ProcessEvent:1201 Send BINDING_REQUEST failed(801A0016)。

    2020-11-08 17:03:07.967086-0500 igkTest【48868:2788074】【ViceroyTrace】【错误】ICEStopConnectivityCheck:2740 ICEStopCnnectivityCheck()未发现带有呼叫id的ICE检查(2014448547)

    2020-11-08 17:03:07.9992298-5000 igkTest[4868:2788203][ViceroyTrace][ERROR]gckSessionCheckPendingConnections:1454 gckSessionCheck PendingConnections:iICEChecksLeft=0,iUnconnectedNodeCount=0,iDDsExpected=0

    #################失败,出现错误##############

    操作无法完成。(ExtensionErrorDomain错误-5900。)

玩家2抛出方法"matherViewController(viewController:error:)",但由于他/她已经接受了邀请,玩家1认为邀请已经被接受,并使用"self.delegate"继续游戏?。presentGame(match:self.match!)'.

这种情况并非每次都会发生,而是每2次或第3次当玩家2过早接受邀请时都会发生。

如果有人能帮忙的话,请提前感谢!

如果有人遇到同样的问题,以下方法会有帮助吗?

func player(_ player: GKPlayer, didAccept invite: GKInvite) {
if matchmakerViewController != nil {
matchmakerViewController!.dismiss(animated: false, completion: nil)
self.matchmakerViewController!.matchmakerDelegate = nil
self.matchmakerViewController = nil
}
let delayTime = DispatchTime.now() + .milliseconds(2000)
DispatchQueue.main.asyncAfter(deadline: delayTime) {
self.matchmakerViewController = GKMatchmakerViewController(invite: invite)
self.matchmakerViewController!.matchmakerDelegate = self
self.delegate?.presentMatchmaking(viewController: self.matchmakerViewController!)
}
}

Dispatch.asyncAfter正在给系统时间来进行完整的";"清理";的matterViewController。我现在正在测试它,但其他人的反馈将不胜感激。

编辑:经过更多的测试,这并不是解决方案;问题还在继续。然而,我注意到,当第二个玩家打开GKMatchmakerViewController的实例时,我没有问题。换句话说,如果我先打电话给presentMatchmaker(),然后接受邀请,它就会工作。因此,例如,当第二个玩家不在游戏中并收到游戏邀请时,就会出现问题。因此,我将代码更改为以下代码,到目前为止似乎有效:

public func player(_ player: GKPlayer, didAccept invite: GKInvite) {
if matchmakerViewController != nil {
matchmakerViewController!.dismiss(animated: false, completion: nil)
self.matchmakerViewController!.matchmakerDelegate = nil
self.matchmakerViewController = nil
}

// THIS HELPS AVOID CRASH.
presentMatchmaker()

let delayTime = DispatchTime.now() + .milliseconds(1000)
DispatchQueue.main.asyncAfter(deadline: delayTime) {
self.matchmakerViewController = GKMatchmakerViewController(invite: invite)
self.matchmakerViewController!.matchmakerDelegate = self
self.delegate?.presentMatchmaking(viewController: self.matchmakerViewController!)
}
}

不是一个非常优雅的解决方案。。。

最新更新