跨设备的游戏数据持久性
Game Data Persistence Across Devices
我仍处于游戏的早期阶段,我正在使用某人制作的 KeyChain 包装器 class 保存信息。早点想请教一下,有时间可以改一下。
我的游戏有可能保留大量关于玩家及其所做行为的数据,例如:
- 玩家有多少金币
- 他们获得了哪些物品(您可以获得大约 50 件物品)
- 他们为自己的角色选择了哪些技能、法术和能力
- 他们的经验水平、最大生命值、统计数据等
我决定将其存储在 KeyChain 中的原因是有人告诉我它已加密并且更难篡改。我觉得还有其他解决方案,例如下面的解决方案,但我写了一些可能不好的潜在原因:
让所有内容都基于网络,并存储在我服务器某处的数据库中 - 我希望我的游戏可以离线玩
使用本地数据库(比方说 FMDB) - 我可以使用工具直接编辑值,让自己更健康,等等。
- 使用核心数据 - 以前从未使用过,不确定这是否与#3 一样容易篡改?
- GameCenter - 以前从未使用过,所以不确定电梯是什么
- NSPreferences - 首选项更容易被篡改(我使用工具可以非常快速地更改值)
所以我不确定我上面的说法是否完全错误,但可以说这在一定程度上是正确的,KeyChain 是一个很好的方法。现在的问题是,如果我想以某种方式允许玩家拿起一个新设备并从他们离开的地方接起怎么办?我究竟如何序列化我保存在钥匙串中的所有数据?我不介意创建一个巨大的 JSON 值文档,并将其发送到某个地方(哪里?到 GameCenter?)
任何正确方向的建议/指示都会很好,尤其是现在,因为我处于早期阶段,可以进行更改以退后一步。
非常感谢大家感谢您的宝贵时间!
为好问题加星!!
我正在做类似的事情。现在,我正在使用 UserDefaults
作为主存储。当我需要传输数据时,我可以将其保存到 iCloudKit
,或者我可以将其导出为 plist
或 json
以用于 AlamoFire、电子邮件等
至于实际存储数据,我看到你提到了 CoreData
.. 这有点过分了!看看 NSCoder
和 NSKeyedArchiver
.
就个人而言,我制作了自己的 save/load 函数来操作字典,然后将它们扔到 UserDefaults
键中。
我如何在 UserDefaults 中存储字典的示例层次结构(有很多方法可以解决这个问题)
密钥:
Items->Equipment->Weapons->WeaponName
值:
{ dictionary of data like AP, Cost, etc }
这对我来说比使用 NSCoder 更容易,而且肯定比 CoreData 更容易!!目标是把所有的东西都变成一个字典,然后你可以很容易地把它放进UserDefaults
,这样你就可以很容易地创建plists或保存到云端。
有了上面的关键系统,你基本上只是做for
循环来找到你需要的东西,解析出每个部分..所以一个显示所有设备的功能,你只需加载整个UserDefaults.standard.dictionaryRepresentation
,然后搜索只有 'Items->Equipment' 等的键。
希望这对您有所帮助!
如果您需要更多提示,我可以分享我游戏中的一些功能。
更新:
如果你要把它做成一个在线游戏,我会首先专注于学习持久性和云使用的基本知识,然后将它移植到一个使用加密的更安全的平台。
最好的办法是创建自己的服务器并以此方式传输数据。这将在您需要时为您提供您想要的东西,并提供您想要的安全性。
如果您想使用 GameCenter
,我会使用 GC 作为您创建的自定义内容的中间层,这样您就可以过滤掉作弊者的分数/具有更大的灵活性。
一些基于经验教训的想法(通常,"the hard way")可能(或可能没有)有帮助。 :)
我在您的 post 中看到了三个要求:离线播放(需要本地存储)、数据安全(这本身就是一个庞大的主题)和同步。
- 可离线播放:
因此您需要某种本地存储。 Keychain,Core Data
,SQL,NSPreferences
都是选项。我不知道 Keychain 的局限性,所以不确定它是否适合连续 read/write 大块数据。
- 数据安全:
他们的钥匙串会在您未登录时保护您的秘密,并在应用程序之间对其进行分区。 https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html and http://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 访问权限,并且可能可以做任何他们想做的事情。
在当今的安全世界中,口头禅通常是,"assume breach." 假设如果他们想要足够糟糕,他们就会找到方法。因此你需要考虑其他层面的防御:划分你的秘密,使泄露的秘密价值有限,静态加密和传输中加密。因此,在写入 it/transmit 之前混淆数据是另一层防御(尽管他们可能仍会编辑它并且您将不得不处理潜在的垃圾值)。
你可以把安全追到兔子洞里很远;您必须决定成本大于收益的地方,and/or 您打算防范的风险。
- 跨设备同步:
因此您需要一个同步解决方案。 iCloud Keychain 在设备之间同步,因此如果钥匙串满足您的存储需求,那么它也可能满足您的同步需求。同样,我不确定是否存在大小或更新频率限制。我没有使用过这个,但是这个 SO 答案提供了更多信息:. Based on Apple's docs (https://support.apple.com/en-us/HT204085) 看起来用户确实必须启用同步才能工作。
否则,Apple 提供 GameCenter
和 CloudKit
。或者您可以探索第 3 方选项。我使用 GameCenter
和 CloudKit
跨设备同步数据。 CloudKit
战胜 GameCenter
,IMO,没有竞争。
使用 GameCenter
,您可以获得多人匹配和用户之间共享数据的渠道。但是,您必须特别遵守其结构,这在 IMO 中非常令人沮丧,而且功能有限。在 SO 上检查 GameCenter
和 GKTurnBasedMatch
标签,了解问题所在。
CloudKit
是一个较低级别的解决方案。它允许您在 iCloud 和 "subscribe" 中存储各种数据对象以更改通知。所有数据都包含在应用程序的容器中,并且有一个 "private"(特定于用户)部分和一个 public(由应用程序的所有用户共享)部分。在 CloudKit
上观看了介绍性的 WWDC 视频后,我立即成功地在不同设备上的 和 不同用户之间同步了用户设置。但是,如果您想要 GameCenter
的某些多人游戏功能,则必须自己构建数据 model/subscriptions。由于支持离线播放,您需要将数据保存到本地存储解决方案并定期上传到 iCloud 进行同步。
结论(又名 TL;DR)
因此,我的意见是:none 这些工具分别满足您的所有三个要求,并且无论您选择哪个选项,您最终都会针对至少 1 个要求推出自己的解决方案.在我的多人游戏中,我相信 Apple 的文件系统(容器)可以提供足够的数据安全性,我在应用程序的容器中使用本地存储选项,并且我定期将 NSData 对象写入 cloudKit 以进行同步跨设备。我用 GameCenter
达到了我的挫败感极限并将其从我的应用程序中删除。
我仍处于游戏的早期阶段,我正在使用某人制作的 KeyChain 包装器 class 保存信息。早点想请教一下,有时间可以改一下。
我的游戏有可能保留大量关于玩家及其所做行为的数据,例如:
- 玩家有多少金币
- 他们获得了哪些物品(您可以获得大约 50 件物品)
- 他们为自己的角色选择了哪些技能、法术和能力
- 他们的经验水平、最大生命值、统计数据等
我决定将其存储在 KeyChain 中的原因是有人告诉我它已加密并且更难篡改。我觉得还有其他解决方案,例如下面的解决方案,但我写了一些可能不好的潜在原因:
让所有内容都基于网络,并存储在我服务器某处的数据库中 - 我希望我的游戏可以离线玩
使用本地数据库(比方说 FMDB) - 我可以使用工具直接编辑值,让自己更健康,等等。
- 使用核心数据 - 以前从未使用过,不确定这是否与#3 一样容易篡改?
- GameCenter - 以前从未使用过,所以不确定电梯是什么
- NSPreferences - 首选项更容易被篡改(我使用工具可以非常快速地更改值)
所以我不确定我上面的说法是否完全错误,但可以说这在一定程度上是正确的,KeyChain 是一个很好的方法。现在的问题是,如果我想以某种方式允许玩家拿起一个新设备并从他们离开的地方接起怎么办?我究竟如何序列化我保存在钥匙串中的所有数据?我不介意创建一个巨大的 JSON 值文档,并将其发送到某个地方(哪里?到 GameCenter?)
任何正确方向的建议/指示都会很好,尤其是现在,因为我处于早期阶段,可以进行更改以退后一步。
非常感谢大家感谢您的宝贵时间!
为好问题加星!!
我正在做类似的事情。现在,我正在使用 UserDefaults
作为主存储。当我需要传输数据时,我可以将其保存到 iCloudKit
,或者我可以将其导出为 plist
或 json
以用于 AlamoFire、电子邮件等
至于实际存储数据,我看到你提到了 CoreData
.. 这有点过分了!看看 NSCoder
和 NSKeyedArchiver
.
就个人而言,我制作了自己的 save/load 函数来操作字典,然后将它们扔到 UserDefaults
键中。
我如何在 UserDefaults 中存储字典的示例层次结构(有很多方法可以解决这个问题)
密钥:
Items->Equipment->Weapons->WeaponName
值:
{ dictionary of data like AP, Cost, etc }
这对我来说比使用 NSCoder 更容易,而且肯定比 CoreData 更容易!!目标是把所有的东西都变成一个字典,然后你可以很容易地把它放进UserDefaults
,这样你就可以很容易地创建plists或保存到云端。
有了上面的关键系统,你基本上只是做for
循环来找到你需要的东西,解析出每个部分..所以一个显示所有设备的功能,你只需加载整个UserDefaults.standard.dictionaryRepresentation
,然后搜索只有 'Items->Equipment' 等的键。
希望这对您有所帮助!
如果您需要更多提示,我可以分享我游戏中的一些功能。
更新: 如果你要把它做成一个在线游戏,我会首先专注于学习持久性和云使用的基本知识,然后将它移植到一个使用加密的更安全的平台。
最好的办法是创建自己的服务器并以此方式传输数据。这将在您需要时为您提供您想要的东西,并提供您想要的安全性。
如果您想使用 GameCenter
,我会使用 GC 作为您创建的自定义内容的中间层,这样您就可以过滤掉作弊者的分数/具有更大的灵活性。
一些基于经验教训的想法(通常,"the hard way")可能(或可能没有)有帮助。 :)
我在您的 post 中看到了三个要求:离线播放(需要本地存储)、数据安全(这本身就是一个庞大的主题)和同步。
- 可离线播放:
因此您需要某种本地存储。 Keychain,Core Data
,SQL,NSPreferences
都是选项。我不知道 Keychain 的局限性,所以不确定它是否适合连续 read/write 大块数据。
- 数据安全:
他们的钥匙串会在您未登录时保护您的秘密,并在应用程序之间对其进行分区。 https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html and http://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 访问权限,并且可能可以做任何他们想做的事情。
在当今的安全世界中,口头禅通常是,"assume breach." 假设如果他们想要足够糟糕,他们就会找到方法。因此你需要考虑其他层面的防御:划分你的秘密,使泄露的秘密价值有限,静态加密和传输中加密。因此,在写入 it/transmit 之前混淆数据是另一层防御(尽管他们可能仍会编辑它并且您将不得不处理潜在的垃圾值)。
你可以把安全追到兔子洞里很远;您必须决定成本大于收益的地方,and/or 您打算防范的风险。
- 跨设备同步:
因此您需要一个同步解决方案。 iCloud Keychain 在设备之间同步,因此如果钥匙串满足您的存储需求,那么它也可能满足您的同步需求。同样,我不确定是否存在大小或更新频率限制。我没有使用过这个,但是这个 SO 答案提供了更多信息:. Based on Apple's docs (https://support.apple.com/en-us/HT204085) 看起来用户确实必须启用同步才能工作。
否则,Apple 提供 GameCenter
和 CloudKit
。或者您可以探索第 3 方选项。我使用 GameCenter
和 CloudKit
跨设备同步数据。 CloudKit
战胜 GameCenter
,IMO,没有竞争。
使用 GameCenter
,您可以获得多人匹配和用户之间共享数据的渠道。但是,您必须特别遵守其结构,这在 IMO 中非常令人沮丧,而且功能有限。在 SO 上检查 GameCenter
和 GKTurnBasedMatch
标签,了解问题所在。
CloudKit
是一个较低级别的解决方案。它允许您在 iCloud 和 "subscribe" 中存储各种数据对象以更改通知。所有数据都包含在应用程序的容器中,并且有一个 "private"(特定于用户)部分和一个 public(由应用程序的所有用户共享)部分。在 CloudKit
上观看了介绍性的 WWDC 视频后,我立即成功地在不同设备上的 和 不同用户之间同步了用户设置。但是,如果您想要 GameCenter
的某些多人游戏功能,则必须自己构建数据 model/subscriptions。由于支持离线播放,您需要将数据保存到本地存储解决方案并定期上传到 iCloud 进行同步。
结论(又名 TL;DR)
因此,我的意见是:none 这些工具分别满足您的所有三个要求,并且无论您选择哪个选项,您最终都会针对至少 1 个要求推出自己的解决方案.在我的多人游戏中,我相信 Apple 的文件系统(容器)可以提供足够的数据安全性,我在应用程序的容器中使用本地存储选项,并且我定期将 NSData 对象写入 cloudKit 以进行同步跨设备。我用 GameCenter
达到了我的挫败感极限并将其从我的应用程序中删除。