При переносе приложения из 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, а переменная existingData содержит действительный 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: Context
- codingPath: 0 elements
- debugDescription: «Указанные данные не содержат значения верхнего уровня.»
- lowerError: nil
Я наткнулся на сообщение без ответа от другого разработчика кто описывает эту же проблему здесь: CoreData NSManagedObject & JSON Encodable не работает
Поскольку JSON действителен и достигнута точка останова внутри initFromDecoder, я не могу подумайте обо всем, что могло бы вызвать этот сбой. Возможно, что-то не так в том, как построен класс. Интересно, сталкивался ли еще кто-нибудь с подобной проблемой.