将自定义对象转换为NSData Swift

时间:2016-12-06 06:24:54

标签: ios swift nscoding

我一直在研究整个interweb,特别是Stack溢出,以及我自己在家里的引用,但我无法弄清楚我的代码有什么问题。我一天中的大部分时间都在努力解决这个问题,我希望这里的人能帮助我指出正确的方向。

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

BoardModel有一个代表棋盘的2D数组。现在,每次移动,我都希望将游戏数据保存在游戏中心,但在我甚至可以尝试存储游戏数据之前,编码会抛出错误,这就是我所处的位置。该错误只是指向AppDelegate,声明为"Thread: 1 signal SIGABRT"

以下是与Piece类一起出现问题的代码:

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
    }
}

1 个答案:

答案 0 :(得分:1)

如果您的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)

Out out is

386 bytes