5

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?

3
  • I'm guessing this is seed 6? Commented Aug 24, 2016 at 1:58
  • Yes! This is Xcode 8 Beta 6. Is this a known bug that NSKeyedArchiver does not work. Commented Aug 24, 2016 at 1:59
  • 1
    No, I just want to make sure we're on the same page... Commented Aug 24, 2016 at 1:59

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

4 Comments

The weird part is that it does not even call the init(coder) or encode(with coder) functions. Even if I remove the enum type in the encode and init I get the same result.
Okay, I have an idea about that too: you might need to cast to NSArray.
Sweet! Thanks @matt! Yup NSArray works. I will accept the answer as soon as I can :) Thanks again!
Added that info the answer, for posterity. Very well asked question: I was able to test your code quite easily.

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.