3

我正在尝试更新我的应用程序以与 iOS10 中 GameCenter 的新功能正常工作。

我在 device1 上创建了一个新的 GKGameSession,获取了一个共享 URL,一切正常。我通过共享表将共享 URL 发送到设备 2。

Device2 单击链接,设备会短暂显示“正在检索...”,然后启动我的应用程序。伟大的!但是,现在呢?我可以通过某种方式访问​​此 URL 是否有可用的上下文信息?否则我无法在应用程序启动时做出响应。

以前,您会收到对遵循 GKLocalPlayerListener 协议的内容的回调,对方法 player:didAcceptInvite: 的回调,您可以通过这种方式加入比赛。但是有了这些基于 iCloud 的消息,玩家甚至可能没有登录到 GameCenter,对吧?这部分似乎在 WWDC 演示文稿中被掩盖了。

此外,截至今天(2016 年 12 月 28 日),没有关于这些新方法的 Apple 文档。

4

2 回答 2

1

由于 GKGameSessionEventListener 回调 session:didAddPlayer: 仅在游戏已经运行时才会触发,因此要确保每次都可以处理此回调,需要解决。我已经对此进行了测试,并且可以正常工作。

当您向游戏发送 iMessage 或电子邮件邀请时,请勿在消息中直接包含游戏会话邀请 URL。而是使用已注册的 URL,当在安装了您的应用程序的设备上打开您的应用程序时,该 URL 将打开您的应用程序。在这里查看如何:

iOS 自定义 URL 方案完整教程

但是添加游戏邀请 URL 的百分比转义编码作为此 URL 的参数(我假设注册了一个 url,例如 newGameRequest 但最好使它非常独特,甚至更好 - 尽管它需要更多设置,尝试通用链接支持,因为这将允许您将未安装您的应用程序的用户引导到带有下载链接的网页)

let openOverWordForPlayerChallenge = "newGameRequest://?token="

gameState.gameSession?.getShareURL { (url, error) in
    guard error == nil else { return }
    // No opponent so we need to issue an invite
    let encodedChallengeURL = url!.absoluteString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
    let nestedURLString = openOverWordForPlayerChallenge + encodedChallengeURL!
    let nestedURL = URL(string: nestedURLString)!
}

通过消息或电子邮件或 WhatsApp 或其他方式发送 URL。然后在您的应用委托中,添加以下内容:

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    var success = false
    if let queryString = url.query {
        if let urlStringToken = queryString.removingPercentEncoding {
            let token = "token="
            let startIndex = urlStringToken.startIndex
            let stringRange = startIndex..<urlStringToken.index(startIndex, offsetBy: token.characters.count)
            let urlString = urlStringToken.replacingOccurrences(of: token, with: "", options: .literal, range: stringRange)
            if let url = URL(string: urlString) {
                if UIApplication.shared.canOpenURL(url) {
                    UIApplication.shared.open(url, options: [:], completionHandler: nil)
                    success = true
                }
            }
        }
    }
    return success
}

现在你可以确定 session:didAddPlayer: 会被调用。有什么赌注这个 workarround 会持续大约 2 周,他们会在 WWDC 2017 展示的下一个 iOS 版本中解决这个问题!更新:这个问题还没有解决 - 所以上面的解决方法仍然很好!

于 2017-05-27T00:43:07.403 回答
0

我同意,缺乏文档令人沮丧。据我所知,我们必须:

  • <GKGameSessionEventListener>在类的标题中添加协议
  • 然后在接受邀请链接后在加入session:didAddPlayer:玩家的设备上触发。

更新: 不幸的是,听到你的结果我并不感到惊讶。我没有尝试过所有这些场景,但GKTurnBasedMatch也有类似的缺点。我解决它的方法是:我添加了一个玩家状态列表以匹配数据(受邀、活跃、退出等)。我给玩家一个“待处理邀请”的视图。当他们打开该视图时,我会加载他们所有的比赛并显示玩家处于邀请状态的条目。使用 GKGameSession,这也应该有效。

或者,如果您可以维护您知道的本地会话列表,可能会更容易。每当游戏激活时,从服务器中拉出整个会话列表并寻找新条目。新条目必须与玩家刚刚通过单击共享 URL 接受的匹配。

于 2016-12-30T00:13:49.423 回答