跨设备的游戏数据持久性

时间:2016-12-17 03:33:56

标签: ios swift sprite-kit game-center keychain

我还处于游戏的早期阶段,我正在使用某人制作的KeyChain包装类来保存信息。我想尽早提出一些建议,因为我有时间改变方法。

我的游戏有可能持续存在大量关于玩家的数据以及他们所做的事情,例如:

  • 玩家拥有多少金币
  • 他们获得了什么物品(你可以获得约50件物品)
  • 他们为角色选择的技能,法术和能力
  • 他们的经验水平,最大健康状况,统计数据等

我决定将其存储在KeyChain中的原因是我被告知它已加密并且更难以篡改。我觉得还有其他解决方案,例如下面的解决方案,但我写了一些潜在的原因,为什么这可能不太好:

  1. 让所有内容都基于网络,并存储在我服务器上的某个数据库中 - 我希望我的游戏可以离线播放

  2. 使用本地数据库(FMDB,比如说) - 我可以使用工具直接编辑值,让自己更健康等等。

  3. 使用核心数据 - 以前从未使用过这个,不确定这是否与#3一样容易被篡改?
  4. GameCenter - 之前从未使用过,所以不确定电梯是什么
  5. NSPreferences - 首选项更容易被篡改(我已经使用工具很快地更改了值)
  6. 所以我不确定我上面是否完全错了,但是让我们说那里有一定程度的道理,KeyChain是一个很好的方法。现在的问题是,如果我想以某种方式允许玩家拿起一个新设备并从他们中断的地方拿起?我如何序列化我在钥匙串中保存的所有数据?我不介意创建一个巨大的值的JSON文档,并将它发送到某个地方(在哪里?到GameCenter?)

    任何正确方向的建议/指示都会很好,特别是现在因为我处于早期阶段,可以做出改变以退一步。

    非常感谢大家感谢你的时间!

2 个答案:

答案 0 :(得分:5)

基于经验教训(通常是“艰难的方式”)的一些想法可能(或可能不)有用。 :)

我在帖子中看到了三个要求:离线播放(需要本地存储),数据安全性(这本身就是一个巨大的话题)和同步。

  • 可离线播放:

因此,您需要某种本地存储。钥匙串,Core Data,SQL,NSPreferences都是选项。我不知道Keychain的局限性,所以不确定它是否适合连续读/写大块数据。

  • 数据安全:

当您未登录时,他们的钥匙串会保护您的秘密,并在应用之间对其进行分区。 https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.htmlhttp://evgenii.com/blog/sharing-keychain-in-ios/提供了更多详细信息。这应该可以防止其他工具在非越狱设备上修改其他应用程序的内容。

Core Data,SQL等将位于您应用的容器中,这使得其他工具更难以在非越狱设备上访问。这里有一个很好的描述:https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html

NSPreferences不提供我所知道的任何安全性。另外,如果他们越狱设备,他们基本上可以在Linux机器上进行root访问,并且可以做他们想做的任何事情。

在今天的安全世界中,咒语通常是“假设违反”。就像在,假设他们想要足够糟糕,他们会找到一个方法。因此,你需要考虑其他防御层:划分你的秘密,以便妥协的秘密价值有限,静态加密和传输加密。因此,在写入/传输之前对数据进行模糊处理是另一层防御(虽然它们仍然可以编辑它,但您必须处理潜在的垃圾值)。

你可以在兔子洞的远处追逐安全;你必须决定成本超过收益的位置,和/或你打算防范的风险。

  • 跨设备同步:

因此,您需要一个同步解决方案。 iCloud Keychain在设备之间同步,因此如果钥匙串满足您的存储需求,这也可能满足您的同步需求。同样,我不确定是否存在大小或更新频率限制。我没有使用过这个,但这个SO答案提供了更多信息:https://stackoverflow.com/a/32606371/1641444。基于Apple的文档(https://support.apple.com/en-us/HT204085),看起来用户必须启用同步才能使其正常工作。

否则,Apple会提供GameCenterCloudKit。或者您可以探索第三方选项。我使用GameCenterCloudKit来跨设备同步数据。 CloudKit胜过GameCenter,IMO,没有竞争。

使用GameCenter,您可以获得多人匹配和渠道,以便在用户之间共享数据。但是,你必须特别坚持IMO的结构,这对IMO来说非常令人沮丧,并且功能有限。检查此处的GameCenterGKTurnBasedMatch标记,了解问题。

CloudKit是一个较低级别的解决方案。它允许您在iCloud中存储各种数据对象,并“订阅”以更改通知。所有数据都包含在应用程序的容器中,并具有“私有”(用户特定)部分和公共部分(由应用程序的所有用户共享)部分。在CloudKit上观看介绍性WWDC视频后,我成功地在不同设备上的设备 AND 之间同步了用户设置。但是,如果您想要GameCenter的某些多人游戏功能,则必须自己构建数据模型/订阅。由于您支持离线播放,因此您需要将数据保存到本地存储解决方案,并定期将其上传到iCloud进行同步。

结论(又名TL; DR)

所以,我的观点是:没有一个工具可以单独满足您的所有三个要求,并且无论您选择哪个选项,您最终都会自行编制至少1个req的解决方案。在我的多人游戏中,我相信Apple的文件系统(容器)以提供足够的数据安全性,我在应用程序的容器中使用本地存储选项,并且我定期将NSData对象写入cloudKit以便跨设备进行同步。我使用GameCenter达到了挫折限制并将其从我的应用中删除。

答案 1 :(得分:2)

明星提出一个好问题!!

我正在做类似的事情。现在,我正在使用UserDefaults进行主存储。当我需要传输数据时,我可以将其保存到iCloudKit,或者我可以将其导出为plistjson以用于AlamoFire,电子邮件等。

至于实际存储数据,我看到你提到CoreData ..这有点矫枉过正!查看NSCoderNSKeyedArchiver

就个人而言,我创建了自己的保存/加载函数来操作字典,然后将它们放入UserDefaults键。

我如何在UserDefaults中存储dicts的示例层次结构(有很多方法可以解决这个问题)

键:

 Items->Equipment->Weapons->WeaponName

值:

 { dictionary of data like AP, Cost, etc }

这对我来说比使用NSCoder更容易,当然比CoreData更容易!!目标是将所有内容都转换为字典,然后您可以轻松地将其放入UserDefaults,这样您就可以轻松创建plist或保存到云端。

使用上面的密钥系统,你基本上只需要for循环来找到你需要的东西,解析每个部分..所以显示所有设备的功能,你只需加载整个UserDefaults.standard.dictionaryRepresentation,然后搜索只有'Items-> Equipment'等的键。

希望这有帮助!

如果您需要更多提示,我可以从我的游戏中分享一些功能。

更新: 如果您将其作为在线游戏,我将首先专注于学习持久性和云使用的基本要素,然后将其移植到使用加密的更安全的平台。

您最好的选择是创建自己的服务器并以这种方式传输数据。这将为您提供您想要的,何时需要,以及您想要的安全性。

如果您想使用GameCenter,我会使用GC作为您创建的自定义内容的中间层,这样您就可以过滤掉作弊者的分数/具有更大的灵活性。

相关问题