0

What I want to do:

I want to get an array from UserDefaults that I saved beforehand and append a custom object to it. Afterwards I want to encode it as a Data-type again and set this as the UserDefaults Key again.

My problem:

The encoding part is what is not working as intended for me. It says: -[__SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x60000011a540

But I do not know how to fix this.

Below is my code for more context:

do {

let decoded  = defaults.object(forKey: "ExArray") as! Data
var exo = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decoded) as! [Exerc]
exo.append(datas[indexPath.row])

let enco = try NSKeyedArchiver.archivedData(withRootObject: exo, requiringSecureCoding: false)   <- Here is the error
defaults.set(enco, forKey: "ExArray")

} catch {

print("Error encoding custom object NOSEARCHO")

}

This is how Exerc looks:

struct Exerc: Codable {
    var title: String
    var exID: String
}
Jan Swoboda
  • 152
  • 2
  • 15
  • As an alternative, I suggest you use `Codable` to convert your array/data in both directions. See [Save Struct to UserDefaults](https://stackoverflow.com/questions/44876420/save-struct-to-userdefaults) – pawello2222 Sep 01 '20 at 23:25
  • By the sounds of the error, you just need to implement the `NSCoding` protocol on your `Exerc` class: https://www.raywenderlich.com/6733-nscoding-tutorial-for-ios-how-to-permanently-save-app-data. I second the `Codable` option if you want to use a more modern API. – Jacob Sep 01 '20 at 23:32
  • @Kubee added now ```struct: Codable {...}```, but it doesnt work. – Jan Swoboda Sep 01 '20 at 23:37
  • 1
    Codable uses JSONEncoder/JSONDecoder. You will have to encode and decode your data using those classes and scrap NSKeyedUnarchiver/NSKeyedArchiver – Jacob Sep 01 '20 at 23:38
  • 1
    Impossible to reply without knowing what an Exerc is. – matt Sep 02 '20 at 00:12
  • So you cannot use Exerc with NSKeyedUnarchiver etc., because it is not compliant with NSCoding. Either that or, as you've been told, scrap NSKeyedUnarchiver and use Codable instead. Pick one. – matt Sep 03 '20 at 01:26
  • I try to do it with Codable now. Any help or direction would be cool! @matt – Jan Swoboda Sep 04 '20 at 00:24

1 Answers1

1

Seems like you are not using the archiver features, so why don't you just use the codable?

do {
    
    let key = "ExArray"
    let decoded = defaults.data(forKey: key)!
    var exo = try JSONDecoder().decode([Exerc].self, from: decoded)
    exo.append(datas[indexPath.row])

    let enco = try JSONEncoder().encode(exo)
    defaults.set(enco, forKey: key)

} catch {
    print("Error encoding/decoding custom object NOSEARCHO", error)
}

It just a simple refactored MVP of the original code, but you can even work a bit on this and make it human readable right in the plist file!

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
  • Solved it myself in the mean time and it looks like your answer. Have to wait 23hrs to give you the bounty. But anyway, thank you. – Jan Swoboda Sep 04 '20 at 00:55