将自定义对象转换为 NSData Swift

converting custom object to NSData Swift

我一直在整个互联网上进行研究,尤其是 Stack overflow,以及我自己在家里的参考资料,但我一直无法弄清楚我的代码有什么问题。我花了一天的大部分时间试图解决这个问题,我希望这里有人能帮助我指明正确的方向。

设置:
我有一个在 Swift 3.0 中构建的国际象棋应用程序,结构如下:BoardModel 是 class,它包含有关游戏的所有数据,Piece 是 class在板模型中,它在 BoardModel 中保存关于自身的数据,Piece 也有一个 PieceType 枚举,用于 .knight、.king 等。

BoardModel 有一个代表棋盘的二维棋子数组。现在,每走一步,我都想将游戏数据保存在 Game Center 中,但在我尝试存储游戏数据之前,编码会抛出一个错误,这就是我所在的位置。该错误仅指向 AppDelegate 并带有以下语句:"Thread: 1 signal SIGABRT"

这是与 Piece 一起出现问题的代码 class:

let pieceData = NSKeyedArchiver.archivedData(withRootObject: board.board[0][0])  // where the error is thrown

class Piece: NSObject, NSCoding {
    var isSelected: Bool
    var type: PieceType
    var isWhite: Bool
    var isFirstMove: Bool
    var symbol: String!
    var position: (row: Int, col: Int)!

    override init() {
        isSelected = false
        type = PieceType.empty
        isWhite = true
        isFirstMove = true
    }

    required init(coder aDecoder: NSCoder) {
        isSelected = aDecoder.decodeBool(forKey: "isSelected")
        type = aDecoder.decodeObject(forKey: "type") as! BoardModel.PieceType
        isWhite = aDecoder.decodeBool(forKey: "isWhite")
        isFirstMove = aDecoder.decodeBool(forKey: "isFirstMove")
        symbol = aDecoder.decodeObject(forKey: "symbol") as! String
        position = aDecoder.decodeObject(forKey: "position") as! (Int, Int)
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(isSelected, forKey: "isSelected")
        aCoder.encode(type, forKey: "type")
        aCoder.encode(isWhite, forKey: "isWhite")
        aCoder.encode(isFirstMove, forKey: "isFirstMove")
        aCoder.encode(symbol, forKey: "symbol")
        aCoder.encode(position, forKey: "position")
    }

    init(isSelected: Bool, type: PieceType, isWhite: Bool, isFirstMove: Bool, symbol: String, position: (Int, Int)) {
        self.isSelected = isSelected
        self.type = type
        self.isWhite = isWhite
        self.isFirstMove = isFirstMove
        self.symbol = symbol
        self.position = position
    }

    func setPosition(to newPosition: (row: Int, col: Int)) {
        position = newPosition
    }
}

如果您的 Enum 是这样 PieceType 并且类型是 Int

enum PieceType : Int {
    case empty
    case notEmpty

}

然后这样写encodedecode方法

 required init(coder aDecoder: NSCoder) {
        isSelected = aDecoder.decodeBool(forKey: "isSelected")
        type = PieceType(rawValue: aDecoder.decodeObject(forKey: "type") as! Int)!
        isWhite = aDecoder.decodeBool(forKey: "isWhite")
        isFirstMove = aDecoder.decodeBool(forKey: "isFirstMove")
        symbol = aDecoder.decodeObject(forKey: "symbol") as! String
        position = aDecoder.decodeObject(forKey: "position") as! (Int, Int)
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(isSelected, forKey: "isSelected")
        aCoder.encode(type.rawValue, forKey: "type")
        aCoder.encode(isWhite, forKey: "isWhite")
        aCoder.encode(isFirstMove, forKey: "isFirstMove")
        aCoder.encode(symbol, forKey: "symbol")
        aCoder.encode(position.row, forKey: "position.row")
        aCoder.encode(position.col, forKey: "position.col")
    }

我已经检查了下面的代码并且它有效

 let pice = Piece(isSelected: true, type: .empty, isWhite: true, isFirstMove: true, symbol: "Test", position: (2, 10))
 let pieceData = NSKeyedArchiver.archivedData(withRootObject:pice)
 print(pieceData)

输出是

386 bytes