首页 > 解决方案 > 如何在 Swift 中从 Realm 保存和加载 GKGameModelPlayer?

问题描述

我正在尝试GKGameModel在我的应用程序中实现 a 。在其中,它包含一些变量,但出于我的问题的目的,我对以下两个变量感兴趣:

import GameplayKit
final class GameModel: NSObject, GKGameModel {
    var players: [GKGameModelPlayer]?
    var activePlayer: GKGameModelPlayer?
}

我做了这样的事情来初始化 3 名玩家的游戏(不准确)

let game = GameModel.init()
game.players = [Player(),Player(),Player()] // Create 3 players
guard let firstPlayer = game.players.first else {
     return
}
game.activePlayer = firstPlayer

一个播放器类定义为:

class Player : NSObject, GKGameModelPlayer {
    var playerId: Int // GKGameModelPlayer protocol variable
    let name: String
    var cash: Int = 0
}

在我的项目中,我有领域实体和分离的模型。所以会有一个PlayerEntity和一个Player类。

我想用来RealmSwift保存和加载GKGameModelPlayer数据,更具体地说是存储/重新存储活动播放器的能力。

我认为这里的关键是playerId变量;但我不确定。

但我不确定的是检索此信息,然后将其重新映射为有效GKGameModelPlayer格式

我目前的想法/理论是我需要将我的模型映射到实体类,反之亦然。

IE:

// [REALM] Player entity
class PlayerEntity: Object {
    @objc dynamic var id = UUID().uuidString
    @objc dynamic var playerId: Int = 0
    @objc dynamic var name: String = ""
    @objc dynamic var cash: Int = 0

    override static func primaryKey() -> String {
       return "id"
    }
}

然后我扩展这个类来做一些“映射”:

extension PlayerEntity {
    // Map model -> entity
    convenience init(model: Player) {
        self.init()

        self.playerId = model.playerId
        self.name = model.name
        self.cash = model.cash
    }
}

extension Player {
    // Map entity -> model
    convenience init(entity: PlayerEntity) {
        let playerId = entity.playerId
        let name = entity.name
        let cash = entity.cash

        self.init(id: playerId, name: name, cash: cash)
    }
}

现在,playerId始终为零 (0),因为我不确定如何设置它。

我可以将玩家保存到服务器。

问题来自当我尝试恢复播放器时,我想恢复 activePlayer 中的变量GameModel

因此,我的问题是:

我将如何保存和恢复activePlayer变量以使其继续遵守GKGameModelPlayer

我很感激这方面的任何帮助。

感谢

标签: swiftrealmgameplay-kit

解决方案


虽然您可以使用这些扩展,但有时越简单越好。这是一个粗略的例子:

class PlayerEntity: Object {
    @objc dynamic var playerId: Int = 0
    @objc dynamic var name: String = ""
    @objc dynamic var cash: Int = 0

    convenience init(withPlayer: PlayerClass) {
       self.init()
       self.playerId = withPlayer.playerId
       self.name = withPlayer.name
       self.cash = withPlayer.cash
    }

    func getPlayer() -> Player {
       let p = Player()
       p.playerId = self.playerId
       p.name = self.name
       p.cash = self.cash
       return p
    }

    override static func primaryKey() -> String {
       return "playerId"
    }
}

将所有玩家加载到一个数组中......这会做到

let playerResults = realm.objects(PlayerEntity.self)
for player in playerResults {
   let aPlayer = player.getPlayer()
   self.playerArray.append(aPlayer)
}

注意删除

@objc dynamic var id = UUID().uuidString

因为它并没有真正用于将对象标识为主键。

主键真的

var playerId: Int // GKGameModelPlayer protocol variable

只要它是独一无二的,就可以使用它。


推荐阅读