Thanks cwrindfuss, finally a sane answer from someone.
I went ahead and saw the lecture. In case someone else wants to see the lecture, it is Lecture 5. Objective-C Compatibilty, Property List, Views.
I paste the actual coding and decoding code here:
var program: AnyObject { // guaranteed to be a PropertyList
get {
return opStack.map { $0.description }
}
set {
if let opSymbols = newValue as? Array<String> {
var newOpStack = [Op]()
for opSymbol in opSymbols {
if let op = knownOps[opSymbol] {
newOpStack.append(op)
} else if let operand = NSNumberFormatter().numberFromString(opSymbol)?.doubleValue {
newOpStack.append(.Operand(operand))
}
}
opStack = newOpStack
}
}
}
The code encodes and decodes an array of Ops to and from Property Lists. Op is an enum.
The coding to PropertyList occurs on line 3. The $0 parameter actually corresponds to an Op enum. The "description" computed property does the actual encoding of Op to PropertyList there.
This will be a crucial point later, so I repeat this: encoding Op to PropertyList is implemented in Op's "description" property.
Decoding of individual Ops, on the other hand, is done on lines 9-12, in the setter of the program property that belongs to CalculatorBrain object.
This is also a crucial point, so I repeat it: decoding Op from PropertyList is not implemented in Op, but in entirely different class (CalculatorBrain).
To sum up:
- Encoding of Op is implemeted in Op enum
- Decoding of Op is implemeted in CalculatorBrain class
This asymmetry is heavily problematic. It works fine for small, educational examples such as the Stanford calculator project. However, this is totally terrible for larger projects. It's a maintenance disaster. Decoding and encoding of type X should happen in one place, ideally in the place where X itself is defined.
This is the case with Objective-C's NSCoding protocol. You implement two methods - initWithCoder: and encodeWithCode: - in the same class, right next to each other, without the need to make any changes to code of any other class/struct/enum/whatever.
I have yet to find a good encoding/decoding architecture that also preserves this property in Swift, particularly when you want to encode/decode enums and structs that cannot conform to the NSCoding protocol. If the enums and structs are generic, the problem becomes even bigger.
Again, the approach outlined in the (very fine, by the way) Stanford course will work for small toy projects, but is not really scalable to larger apps with more complicated models.