I've done a lot of NSCoding archiving in Obj-C, but I'm not sure how it handles structs in Swift, nor arrays with optional values. Here is my code:
public struct SquareCoords {
var x: Int, y: Int
}
and here is the class which I need to store:
public class Player: NSCoding {
var playerNum: Int
var name = ""
private var moveHistory: [SquareCoords?] = []
init (playerNum: Int, name: String) {
self.playerNum = playerNum
self.name = name
}
public required init(coder aDecoder: NSCoder!) {
playerNum = aDecoder.decodeIntegerForKey("playerNumKey")
name = aDecoder.decodeObjectForKey("nameKey") as String
moveHistory = aDecoder.decodeObjectForKey("moveHistoryKey") as [SquareCoords?]
}
public func encodeWithCoder(aCoder: NSCoder!) {
aCoder.encodeInteger(playerNum, forKey: "playerNumKey")
aCoder.encodeObject(name, forKey: "nameKey")
aCoder.encodeObject(moveHistory, forKey: "moveHistoryKey")
}
...
On the last line of the coder init, I get the following error message in XCode:
'AnyObject' is not convertible to [SquareCoords?]'
and on the last line of encodeWithEncoder:
Extra argument 'forKey' in call
Can anyone get me moving in the right direction?
In The Swift Programming Language, Apple states:
Swift provides two special type aliases for working with non-specific types:
-AnyObject
can represent an instance of any class type.
-Any
can represent an instance of any type at all, including function types.
Knowing that, type SquareCoords
(Swift Structure) and type [SquareCoords]
(Swift array of Swift Structure) can't conform to protocol AnyObject
.
On the other hand, decodeObjectForKey:
requires a parameter that conforms to protocol AnyObject
, and encodeObject:forKey:
returns AnyObject
. Thus, the two following lines can't compile:
moveHistory = aDecoder.decodeObjectForKey("moveHistoryKey") as [SquareCoords?]
aCoder.encodeObject(moveHistory, forKey: "moveHistoryKey")
Therefore, unless you find a way to make SquareCoords
conform to protocol AnyObject
(I don't know if it's possible), you will have to transform SquareCoords
from Swift Structure to Class.
PS:
At this point, you may ask: "OK, but how is it possible that type String
- that is in fact a Swift Struct - can conform to protocol AnyObject
?" Well, that's because String
is bridged seamlessly to Foundation’s NSString
class (Array
, Dictionary
are bridged to NSArray
and NSDictionary
the same way). Read this blog post if you want to have a better look at it.