无法将自定义对象从 API 保存到核心数据

Posted

技术标签:

【中文标题】无法将自定义对象从 API 保存到核心数据【英文标题】:Having trouble saving custom objects to core data from an API 【发布时间】:2018-02-17 18:11:44 【问题描述】:

我正在从在线 API 接收 JSON 数据,我正在尝试将数据放入自定义 TVShow 对象,然后使用 CoreData 保存这些对象。我可以正确打印从 JSON 对象获得的值,但是当我尝试创建 TVShow 对象并使用 CoreData 保存它们时出现错误。有什么建议吗?

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()
                        
                    
    
                
            

我收到此错误:

[_SwiftValue encodeWithCoder:]:无法识别的选择器发送到实例 0x6080000a8160

2018-02-15 10:42:38.448476-0800 TV Core Data[81985:5602062] *** -[NSKeyedArchiver dealloc]:警告:NSKeyedArchiver 在没有调用 -finishEncoding 的情况下被释放。

2018-02-15 10:42:38.458710-0800 TV Core Data[81985:5602062] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[_SwiftValue encodeWithCoder:]:无法识别的选择器发送到实例

然而,当我手动创建对象时,使用 for 循环,这行代码可以工作

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()
            
        

【问题讨论】:

【参考方案1】:

缺少 NSCoding 协议的实现。

NSKeyedArchiver 编码(保存)和解码(检索)您想要持久化的任何符合 NSCoding 的类。虽然 NSKeyedArchiver 不如 Core Data 健壮(它速度较慢且需要手动操作),但它完成了持久数据的预期工作,并且比 Core Data 更简单。

NSCoding 是一个需要两种方法的协议 —— 需要 init(coder decoder: NSCoder) 和 encode(with coder: NSCoder)。如果我创建了一个符合 NSObject 和 NSCoder 的类,那么我的类可以被序列化(从其当前数据结构转换为可以存储为字节的格式)和反序列化(从字节提取到数据结构)成可以保存到用户的磁盘。

示例代码:

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)
    

【讨论】:

以上是关于无法将自定义对象从 API 保存到核心数据的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义对象从异步操作过滤器传递到 ASP.net 核心中的控制器?

将自定义数组保存到 Core Data

如何将自定义 ObjectId 添加到解析服务器对象?

将自定义可序列化对象绑定到控件,以便用户和加载/保存首选项

将自定义对象转换为要保存在 NSUserDefauts 中的数据

如何将自定义对象的集合存储到 user.config 文件中?