基于 iMessaged 的​​ GameCenter 邀请 iOS 10

iMessaged-based invitations for GameCenter for iOS 10

我正在尝试更新我的应用程序以正确使用 iOS10 中 GameCenter 的新功能。

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

Device2 单击 link,设备短暂显示 'Retrieving...',然后启动我的应用程序。伟大的!但是,现在呢?是否有我可以以某种方式访问​​的此 URL 的上下文信息?否则我没办法在应用启动时如何响应。

以前你会得到一个回调到遵循 GKLocalPlayerListener 协议的东西,方法 player:didAcceptInvite:,你可以那样加入比赛。但是有了这些基于 iCloud 的消息,玩家可能甚至没有登录到 GameCenter,对吧?这部分似乎在 WWDC 演示中被掩盖了。

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

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

  • 在 class 中添加 <GKGameSessionEventListener> 协议' header
  • 然后 session:didAddPlayer: 加入 玩家的设备上触发 link 接受邀请后。

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

或者,如果您可以维护一个您知道的本地会话列表,这可能会更容易。每当游戏开始运行时,从服务器中提取整个会话列表并查找新条目。新条目必须是玩家刚刚通过单击分享 URL.

接受的比赛

由于 GKGameSessionEventListener 回调 session:didAddPlayer:仅当游戏已经 运行 时才会触发,以确保您每次都可以处理此回调需要一个解决方法。我已经对此进行了测试并且有效。

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

Complete Tutorial on iOS Custom URL Schemes

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

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: 将被调用。打赌这个解决方案可以持续大约 2 周,他们会在 WWDC 2017 展示的下一版 iOS 中解决这个问题!更新:此问题尚未解决 - 因此上述解决方法仍然有效!