基于iMessage的iOS 10 GameCenter邀请

3

我正在尝试更新我的应用程序,以便与iOS10中的GameCenter新功能正确地配合使用。

我在设备1上创建了一个新的GKGameSession,获取了共享URL,一切都很顺利。然后我通过共享表单将共享URL发送到设备2。

设备2点击链接后,设备会短暂地显示“检索...”,然后启动我的应用程序。太好了!但是,现在该怎么办呢?是否有可用于此URL的上下文信息,可以让我以某种方式访问?否则,当应用启动时,我就无法响应。

之前,您会得到一个回调到符合GKLocalPlayerListener协议的内容,即player:didAcceptInvite:方法,并且您可以通过这种方式加入比赛。但是对于这些基于iCloud的消息,玩家可能甚至没有登录GameCenter,对吧?在WWDC演示中似乎忽略了这一部分。

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


嗨,肖恩,你能接受我的答案吗?我认为这是你能得到的最接近解决方案。这是一个很好的解决方法。 - TheBasicMind
2个回答

1

由于GKGameSessionEventListener回调session:didAddPlayer:只有在游戏已经运行时才触发,为了确保每次都能处理这个回调,需要采用一种解决方法。我已经测试过并且可行。

当您向游戏发送iMessage或电子邮件邀请时,请不要直接在消息中包含游戏会话邀请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)!
}

将URL发送到消息、电子邮件、WhatsApp或任何其他应用中。然后在您的应用程序委托中添加以下内容:

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:方法会被调用。这个解决方法可能只能持续两周左右,因为他们可能在2017 WWDC展示的下一个iOS版本中修复这个问题!更新:这个问题还没有被解决 - 所以上面的解决方法仍然有效!

0

我同意,缺乏文档真是令人沮丧。从我的观察来看,我们需要:

  • 在类的头文件中添加<GKGameSessionEventListener>协议
  • 然后,在接受邀请链接后,session:didAddPlayer:会在“加入”玩家的设备上触发。

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

或者,如果您能维护一个本地会话列表,可能会更容易。每当游戏变为活动状态时,从服务器拉取整个会话列表,并查找新条目。新条目必须是玩家刚刚通过单击共享URL接受的比赛。


我已经检查过了,假设加入游戏的玩家已经安装了应用并且它在后台运行。如果没有安装或者应用是冷启动的,它将不会调用此方法。如果您有不同的看法,请回复。 - Shaun Budhram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接