Swift enum and NSCoding
Asked Answered
N

2

4

I have a 'Thing' object with a String property and an NSImage property; the Thing class has encodeWithCoder: and decodeWithCoder: methods, and I can archive and unarchive a [Thing] array using NSKeyedArchiver/Unarchiver.

So far, so good. Now I want to expand my Thing class by an array of directions, where 'Direction' is the following enum:

enum Direction{

case North(direction:String)
case East(direction:String)
case South(direction:String)
case West(direction:String)

}

In other words, the data I wish to store is

thing1.directions: Direction = [.North("thing2"), .South("thing3")]

(In a more perfect world, I'd be using direct references to my Things rather than just their names, but I realise that this will easily create reference cycles - can't set a reference to another Thing until that Thing has been created - so I'll refrain. I'm looking for a quick and dirty method to save my app data and move on.)

Since I will be needing directions elsewhere, this is a separate entity, not just an enum inside the Thing class. (Not sure whether that makes a difference.)

What is the best way to make my Direction enum conform to NSCoding? The best workaround I can come up with involves creating a [String: String] dictionary with "North" and "South" as keys and "thing2" and "thing3" as values, and reconstruct my enum property from that, but is there a better way? And for that matter, is there a way to make tuples conform to NSCoding because right now (String, String) gets me a 'not compatible to protocol "AnyObject"' error.

Many thanks.

Nephro answered 20/10, 2014 at 17:17 Comment(0)
F
5

What I do is give the enum a type and encode and decode its raw value, or else implement description for the enum and encode and decode that string. Either way (or if you use some other way), you obviously need a way to convert in both directions between an enumerator and an archivable type.

Facet answered 20/10, 2014 at 17:25 Comment(4)
how do you encode / decode description? For instance, the following throws an initialization error: Direction(description: (aDecoder.decodeObjectForKey("direction") as! String)) ?? .NorthDesignate
@Designate Ask it as a question, not as a comment, please! There's no room to talk about it here... :)Facet
thanks for the answer, it's time I buy your book(s) :-)Designate
@Designate and in fact it covers this situation: apeth.com/swiftBook/ch04.html#_enum_initializersFacet
H
2

Yes you need to access the enum from the RAW value. Full example and discussion here:

How do I encode enum using NSCoder in swift?

Note this change in Xcode 6.1 " move code from the old-style “fromRaw()/toRaw()” enum APIs to the new style-initializer and “rawValue” property"

https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html

Hazlett answered 20/10, 2014 at 17:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.