将应用程序从Realm迁移到CoreData时,我正在尝试解析以下JSON结构:
{
"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/working-with-codable-and-core-data-83983e77198e
这是模型。它继承自自动生成的“ ManagedProfile”类:
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库成功对其进行了编码,以确保其有效)
do
{
let result = try jsonDecoder.decode(T.self,from: existingData)
DispatchQueue.main.async{
completionHandler(NetworkResult<T>.success(result))}
}
catch let error {
...
}
这是我收到的错误:
▿valueNotFound:2个元素
- .0:TwoVerte.ManagedProfileCodable
▿.1:上下文
- codingPath:0个元素
- debugDescription:“给定的数据不包含顶级值。”
- underlyingError:无
我遇到了另一位开发人员的未回答帖子,他在此处描述了相同的问题:CoreData NSManagedObject & JSON Encodable not working
由于JSON有效且到达了initFromDecoder内部的断点,所以我想不出任何可能导致此失败的原因。建立类的方式可能出了问题。我想知道是否还有其他人也遇到过类似的问题。