GKSavedGame не сохраняется и не загружается обратно

#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 включен в возможности приложения (и тренировки для других вещей, таких как таблицы лидеров)

Возможности GameCenter

После перезапуска приложения и вызова loadSavedGame gameData свойство не восстанавливается в прежнее состояние. Что не так с этим кодом?

Примечание: Я протестировал его как на симуляторе, так и на своем собственном iPhone (реальное ежедневное устройство, на котором GameCenter и iCloud работают с другими приложениями), и он никогда ничего не сохраняет.

Ответ №1:

После включения функций iCloud в документах iCloud и создания контейнера для приложения он теперь работает. В документации об этом ничего нет.

Возможность iCloud