GKSavedGame 未保存或加载回来
GKSavedGame is not saved or loading back
我正在尝试使用 GameKit 中的 GKSavedGame
保存玩家游戏数据,但它不起作用,而且我没有收到任何错误。 (数据没有保存吗?数据没有加载回来吗?)
其中一个问题是 GKSavedGame
没有很好的文档记录(没有我们可以找到的其他示例),所以我们真的不知道如何正确实施它(例如什么是最佳实践?)
我正在使用一个简单的 struct GameData: Codable
来存储游戏数据,我使用 JSONEncoder
/JSONDecoder
对其进行编码。这是我的 GameService
class 部分不起作用:
class GameService {
// Shared instance
static let shared = GameService()
// Properties
private(set) var isGameLoaded = false
private(set) var gameData: GameData?
// Methods
func loadSavedGame(completionHandler: @escaping () -> Void) {
// Check game is not loaded yet
if isGameLoaded {
completionHandler()
return
}
// Get player
let localPlayer = GKLocalPlayer.local
if localPlayer.isAuthenticated {
localPlayer.fetchSavedGames { games, error in
// Iterate saved games
var game: GKSavedGame?
for currentGame in games ?? [] {
if game == nil || game?.modificationDate ?? Date() < currentGame.modificationDate ?? Date() {
game = currentGame
}
}
// If one found, load its data
if let game = game {
game.loadData { data, error in
if let data = data {
self.gameData = try? JSONDecoder().decode(GameData.self, from: data)
}
self.isGameLoaded = true
self.initGameData()
completionHandler()
}
} else {
self.isGameLoaded = true
self.initGameData()
completionHandler()
}
}
}
}
func saveGame() {
// Get player
let localPlayer = GKLocalPlayer.local
if localPlayer.isAuthenticated, let gameData = gameData, let data = try? JSONEncoder().encode(gameData) {
// Save its game data
localPlayer.saveGameData(data, withName: "data") { savedGame, error in
if let error = error {
print(error.localizedDescription)
}
}
}
}
func initGameData() {
// If game data is undefined, define it
if gameData == nil {
gameData = GameData()
}
}
func gameEnded(level: Level, score: Int64) {
// Here I edit my `gameData` object before saving the changes
// I known that this method is called because the data is up to date in the UI
// ...
saveGame()
}
}
此外,GameCenter 在应用程序功能中启用(以及排行榜等其他功能的锻炼)
重新启动应用程序并调用 loadSavedGame
后,gameData
属性 不会恢复到之前的状态。
这段代码有什么问题?
注意:我在模拟器和我自己的 iPhone(GameCenter 和 iCloud 与其他应用程序一起工作的真实日常设备)上对其进行了测试,它从不保存任何内容。
在 Capabilities、iCloud Documents 中启用 iCloud 并为应用程序创建容器后,它现在可以工作了。文档中没有关于此的内容。
我正在尝试使用 GameKit 中的 GKSavedGame
保存玩家游戏数据,但它不起作用,而且我没有收到任何错误。 (数据没有保存吗?数据没有加载回来吗?)
其中一个问题是 GKSavedGame
没有很好的文档记录(没有我们可以找到的其他示例),所以我们真的不知道如何正确实施它(例如什么是最佳实践?)
我正在使用一个简单的 struct GameData: Codable
来存储游戏数据,我使用 JSONEncoder
/JSONDecoder
对其进行编码。这是我的 GameService
class 部分不起作用:
class GameService {
// Shared instance
static let shared = GameService()
// Properties
private(set) var isGameLoaded = false
private(set) var gameData: GameData?
// Methods
func loadSavedGame(completionHandler: @escaping () -> Void) {
// Check game is not loaded yet
if isGameLoaded {
completionHandler()
return
}
// Get player
let localPlayer = GKLocalPlayer.local
if localPlayer.isAuthenticated {
localPlayer.fetchSavedGames { games, error in
// Iterate saved games
var game: GKSavedGame?
for currentGame in games ?? [] {
if game == nil || game?.modificationDate ?? Date() < currentGame.modificationDate ?? Date() {
game = currentGame
}
}
// If one found, load its data
if let game = game {
game.loadData { data, error in
if let data = data {
self.gameData = try? JSONDecoder().decode(GameData.self, from: data)
}
self.isGameLoaded = true
self.initGameData()
completionHandler()
}
} else {
self.isGameLoaded = true
self.initGameData()
completionHandler()
}
}
}
}
func saveGame() {
// Get player
let localPlayer = GKLocalPlayer.local
if localPlayer.isAuthenticated, let gameData = gameData, let data = try? JSONEncoder().encode(gameData) {
// Save its game data
localPlayer.saveGameData(data, withName: "data") { savedGame, error in
if let error = error {
print(error.localizedDescription)
}
}
}
}
func initGameData() {
// If game data is undefined, define it
if gameData == nil {
gameData = GameData()
}
}
func gameEnded(level: Level, score: Int64) {
// Here I edit my `gameData` object before saving the changes
// I known that this method is called because the data is up to date in the UI
// ...
saveGame()
}
}
此外,GameCenter 在应用程序功能中启用(以及排行榜等其他功能的锻炼)
重新启动应用程序并调用 loadSavedGame
后,gameData
属性 不会恢复到之前的状态。
这段代码有什么问题?
注意:我在模拟器和我自己的 iPhone(GameCenter 和 iCloud 与其他应用程序一起工作的真实日常设备)上对其进行了测试,它从不保存任何内容。
在 Capabilities、iCloud Documents 中启用 iCloud 并为应用程序创建容器后,它现在可以工作了。文档中没有关于此的内容。