ɯɐɹʞ
ɯɐɹʞ

Reputation: 1068

converting custom object to NSData Swift

I have been researching all over the interweb, especially Stack overflow, and my own references I have at home, but I have not been able to figure out what is wrong with my code. I have spent most of my day trying to figure this issue out, and I hope somebody here can help point me in the correct direction.

Setup:
I have a chess app that I am building in Swift 3.0, and the structure is as follows: BoardModel is the class that holds all of the data about the game, Piece is a class within board model which holds data about itself within the BoardModel, Piece also has a PieceType enum for .knight, .king, etc.

The BoardModel has a 2D array of Piece representing the chess board. Now, with each move, I want to save the game data in Game Center, but before I can even try to store the game data, the encoding throws an error and that is where I am. The error just points at AppDelegate with the statement: "Thread: 1 signal SIGABRT".

Here is the code that is the problem along with the 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
    }
}

Upvotes: 1

Views: 4882

Answers (1)

jignesh Vadadoriya
jignesh Vadadoriya

Reputation: 3310

if your Enum is like this PieceType and type is Int

enum PieceType : Int {
    case empty
    case notEmpty

}

Then write encode and decode method like this way

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

i have check bellow code and it work's

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

And Out put is

386 bytes

Upvotes: 1

Related Questions