Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSKeyedArchiver Custom Object Array

Tags:

ios

swift

NOTE: Xcode 8 Beta 6

I am not sure what I am missing but for some reason I am getting the following error on the NSKeyedArchiver.archivedData line.

'NSInvalidArgumentException', reason: '-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x60000024c690'
*** First throw call stack:

Here is my class which conforms to the NSCoding protocol:

enum PhraseType {
    case create
    case item
}

class Phrase: NSObject, NSCoding {

    var englishPhrase :String!
    var translatedPhrase :String!
    var phraseType :PhraseType! = PhraseType.item

    required init?(coder decoder: NSCoder) {

        self.englishPhrase = decoder.decodeObject(forKey: "englishPhrase") as! String
        self.translatedPhrase = decoder.decodeObject(forKey: "translatedPhrase") as! String
        self.phraseType = decoder.decodeObject(forKey: "phraseType") as! PhraseType
    }

    func encode(with coder: NSCoder) {

        coder.encode(self.englishPhrase, forKey: "englishPhrase")
        coder.encode(self.translatedPhrase, forKey: "translatedPhrase")
        coder.encode(self.phraseType, forKey: "phraseType")
    }

    init(englishPhrase :String, translatedPhrase :String) {

        self.englishPhrase = englishPhrase
        self.translatedPhrase = translatedPhrase

        super.init()
    }

}

And here is the code for the archiving:

 let userDefaults = UserDefaults.standard
        var phrases = userDefaults.object(forKey: "phrases") as? [Phrase]

        if phrases == nil {
            phrases = [Phrase]()
        }

        phrases?.append(phrase)

        let phrasesData = NSKeyedArchiver.archivedData(withRootObject: phrases)

        userDefaults.set(phrasesData, forKey: "phrases")
        userDefaults.synchronize()

Any ideas?

like image 971
john doe Avatar asked Aug 24 '16 01:08

john doe


1 Answers

You can't encode a Swift enum such as PhraseType. Instead, give this enum a raw value and encode the raw value (and on decode, use that to reconstruct the correct enum case).

When you've done that, you'll need to cast your Swift array to NSArray to get it archived properly.

like image 95
matt Avatar answered Sep 28 '22 08:09

matt