无法将自定义对象从 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 核心中的控制器?