#ios #swift #gamekit
Вопрос:
Я пытаюсь сохранить игровые данные игрока, используя GKSavedGame
GameKit, но это не работает, и я не получаю никаких ошибок. (Данные не сохраняются? Данные не загружаются обратно?)
Одна из проблем заключается в том, что GKSavedGame
это недостаточно документировано (нет примеров, подобных тем, которые мы можем найти для других вещей), поэтому мы действительно не знаем, как это правильно реализовать (например, каковы наилучшие методы?)
Я использую простой struct GameData: Codable
для хранения игровых данных, которые я кодирую с помощью JSONEncoder
/ JSONDecoder
. Вот мой GameService
класс с той частью, которая не работает:
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 работают с другими приложениями), и он никогда ничего не сохраняет.