尝试将json解码为NSManagedObject时,给定数据不包含顶级值错误 [英] The given data did not contain a top-level value error when attempting to decode json into NSManagedObject
问题描述
将应用程序从Realm迁移到CoreData时,我试图解析以下JSON结构:
While migrating an app from Realm to CoreData, I'm attempting to parse the following JSON structure:
{
"username": "972542052677",
"displayName": "Arik",
"countryCode": "972",
"status": "Busy",
"walletPublicKey": "XgWDiGMFRPDRVnRq8nxu7NyMLuT4Uez7mJ",
"lastSeen": "2020-08-05T08:12:57.5267881",
"isOnline": false
}
我需要从该数据创建一个NSManagedObject,因此我在关注本教程: https://medium.com/@andrea.prearo/使用可编码和核心数据83983e77198e
I need to create an NSManagedObject from this data so I'm following this tutorial: https://medium.com/@andrea.prearo/working-with-codable-and-core-data-83983e77198e
这是模型.它从自动生成的"ManagedProfile"继承.课:
This is the model. It inherits from the automatically generated "ManagedProfile" class:
class ManagedProfileCodable: ManagedProfile, Codable {
enum CodingKeys: String, CodingKey {
case username = "username"
case displayName = "displayName"
case email = "email"
case status = "status"
case walletPublicKey = "walletPublicKey"
case countryCode = "countryCode"
case isOnline = "isOnline"
case lastSeen = "lastSeen"
}
// MARK: - Decodable
required convenience init(from decoder: Decoder) throws {
guard let codingUserInfoKeyManagedObjectContext = CodingUserInfoKey.managedObjectContext else{
fatalError("Failed to get codingUserInfoKeyManagedObjectContext")
}
guard let managedObjectContext = decoder.userInfo[codingUserInfoKeyManagedObjectContext] as? NSManagedObjectContext else{
fatalError("Failed to get context from decoder")
}
guard let entity = NSEntityDescription.entity(forEntityName: "ManagedProfile", in: managedObjectContext) else {
fatalError("Failed to read entity desc")
}
self.init(entity: entity, insertInto: managedObjectContext)
let container = try decoder.container(keyedBy: CodingKeys.self)
self.username = try container.decodeIfPresent(String.self, forKey: .username)
self.displayName = try container.decodeIfPresent(String.self, forKey: .displayName)
self.email = try container.decodeIfPresent(String.self, forKey: .email)
self.status = try container.decodeIfPresent(String.self, forKey: .status)
self.walletPublicKey = try container.decodeIfPresent(String.self, forKey: .walletPublicKey)
self.isOnline = try container.decodeIfPresent(Bool.self, forKey: .isOnline) ?? false
self.countryCode = try container.decodeIfPresent(String.self, forKey: .countryCode)
}
// MARK: - Encodable
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(username, forKey: .username)
try container.encode(username, forKey: .displayName)
try container.encode(username, forKey: .email)
try container.encode(username, forKey: .countryCode)
try container.encode(username, forKey: .lastSeen)
try container.encode(username, forKey: .walletPublicKey)
try container.encode(username, forKey: .status)
try container.encode(username, forKey: .isOnline)
}}
这是解码器:
var jsonDecoder : JSONDecoder = {
let decoder = JSONDecoder()
if let appDelegate = UIApplication.shared.delegate as? AppDelegate{
if let codingUserInfoKeyManagedObjectContext = CodingUserInfoKey.managedObjectContext{
decoder.userInfo[codingUserInfoKeyManagedObjectContext] = appDelegate.persistentContainer.viewContext
}
}
return decoder
}()
这是进行实际解码的部分.T代表ManagedProfileCodable,并且existData变量包含一个有效的json(我使用较旧的JSONSerialization库成功对其进行了编码,以确保其有效)
This is the part that does the actual decoding. T stands for ManagedProfileCodable, and the existingData variable holds a valid json (I encoded it successfully using the older JSONSerialization library to make sure it is valid)
do
{
let result = try jsonDecoder.decode(T.self, from: existingData)
DispatchQueue.main.async{
completionHandler(NetworkResult<T>.success(result))}
}
catch let error {
...
}
这是我收到的错误:
▿valueNotFound:2个元素
▿ valueNotFound : 2 elements
- .0:TwoVerte.ManagedProfileCodable
▿.1:上下文
- codingPath:0个元素
- debugDescription:给定的数据不包含顶级值."
- underlyingError:无
我在这里遇到了另一位开发人员的未答复帖子,他对此问题进行了描述:CoreData NSManagedObject&JSON Encodable无法正常工作
I came across an unanswered post from another developer who describes this same issue over here: CoreData NSManagedObject & JSON Encodable not working
由于JSON有效并且到达了initFromDecoder内部的断点,所以我想不出任何可能导致此失败的原因.建立类的方式可能出了问题.我想知道是否还有其他人也遇到过类似的问题.
Since the JSON is valid and the break point inside the initFromDecoder is reached, I can't think of anything that might cause this failure. Probably something is wrong in the way the class is built. I wonder if anyone else has also encountered a similar issue.
推荐答案
我终于解决了这个问题.代替使用"Codegen:类定义",我应该使用"Codegen:手册".并添加如下子类:
I have finally resolved the issue. Instead using "Codegen: Class Definition", I should have used "Codegen: Manual" and add the subclass like this:
- 打开数据模型文件
- 在实体下,选择相关实体
- 从上方菜单中选择编辑器"->创建NSManagedObject子类...
这篇关于尝试将json解码为NSManagedObject时,给定数据不包含顶级值错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!