1

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
    }
}
3
  • what is PieceType? is Enum or Custom object(NSObject)? Commented Dec 6, 2016 at 6:27
  • @jigneshVadadoriya the PieceType is enum Commented Dec 6, 2016 at 6:33
  • Have you provided an NSCoder for the position data type? Try to comment out the position from your code and see if you still crash. You will probably need to provide an NSCoder for the PieceType too depending upon how you implemented it. Commented Dec 6, 2016 at 7:12

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

8 Comments

this only works with blank pieces like you have instantiated in your example. It won't work with----------------------- let somePiece = BoardModel.Piece(isSelected: false, type: BoardModel.PieceType.knight, isWhite: true, isFirstMove: true, symbol: "Wknight", position: (0, 1))
I removed the position instance and that worked, but I need the position, so I need to figure out to do. @jvarela, commented on my question and said to provide an NSCoder for position, but I am unsure of how to do this. jignesh, do you have any idea of how best to do this?
let me try on other way
can you add the code of PieceType enum? in your question
the PieceType isn't an issue, what you added for PieceType is perfect, but it's the position tuple that is throwing the error, so I think I will just remove the tuple from piece, and just have a row and a column variable for each piece to indicate the position both as Integer
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.