0
votes

I am receiving JSON data from an online API and I'm trying to put the data into custom TVShow objects and then saving these objects with CoreData. I can correctly print the values that I obtain from the JSON object, but when I try to create the TVShow objects and save them with CoreData I get an error. Any Suggestions?

Alamofire.request("https://api.tvmaze.com/shows?page=0").responseJSON { 
(responseData) -> Void in
            if((responseData.result.value) != nil) {
                let swiftyJsonVar = JSON(responseData.result.value!)
                //print(swiftyJsonVar)
                for item in swiftyJsonVar.array! {
                    print(item["name"].stringValue)
                    print(item["genres"].arrayValue)
                    print(Int32(item["id"].intValue))
                    print(item["type"].stringValue)
                    print(item["language"].stringValue)
                    print(item["summary"].stringValue)
                
                
                    if CoreDataHandler.saveObject( 
                        id:Int32(item["id"].intValue), 
                        name:item["name"].stringValue, 
                        type:item["type"].stringValue, 
                        language:item["language"].stringValue, 
                        summary:item["summary"].stringValue, 
                        genres:item["genres"].arrayValue) {
                            self.tvshows = CoreDataHandler.fetchObject()
                        }
                    }
    
                }
            }

I am getting this error:

[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x6080000a8160

2018-02-15 10:42:38.448476-0800 TV Core Data[81985:5602062] *** -[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it.

2018-02-15 10:42:38.458710-0800 TV Core Data[81985:5602062] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance

When I create objects manually, however, with a for loop this line of code works

for item in 1...10 {
            
            if CoreDataHandler.saveObject(id: Int32(item), name: "tim\(item)", type: "drama\(item)", language: "english", summary: "\(item) time running out", genres: ["suspense","drama"]) {
                self.tvshows = CoreDataHandler.fetchObject()
            
        }

enter image description here

1

1 Answers

0
votes

Missing implementation of NSCoding protocol.

NSKeyedArchiver encodes (saves) and decodes (retrieves) any NSCoding compliant classes you want persisted. While NSKeyedArchiver is not as robust as Core Data (it’s slower and manual), it accomplishes the desired job of persisting data and can be less complex than Core Data.

NSCoding is a protocol that requires two methods — required init(coder decoder: NSCoder) and encode(with coder: NSCoder). If I create a class that conforms to NSObject AND NSCoder, then my class can be serialized (translated from its current data structure into a format that can be stored as bytes) and deserialized (extracted from bytes into a data structure) into data that can be saved to a user’s disk.

Example code:

class Example : NSObject, NSCoding {

    struct Keys {
        static let Name = "name"
    }

    var name: String

    init(name: String) {
        self.name = name
    }

    required init?(coder aDecoder: NSCoder) {
        guard let decodedName = aDecoder.decodeObject(forKey: Keys.Name) as? String else {
            return nil
        }
        self.name = decodedName
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.name, forKey: Keys.Name)
    }
}