Итак, я пытаюсь согласовать свои классы моделей с NSManagedObject (для постоянства CoreData) и Codable (для сериализации / десериализации JSON).Прямо сейчас мой JSON-декодер проходит примерно половину процесса десериализации, прежде чем завершится с ошибкой
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Land setGun:]: unrecognized selector sent to instance 0x60400028f780'
Я следовал руководству по соответствию обоим модельным протоколам, найденным здесь Какиспользовать swift 4 Codable в Core Data? , и я понимаю, что ошибка выдается, потому что (если верить в ошибку) класс Land не имеет метода setGun.Что меня поражает, так это
A) Ошибка не возникает, когда я декодирую класс JSON Land (он обрабатывает это без проблем), последняя точка прерывания, которая должна быть достигнута, фактически находится в декодере JSON класса Sea.
B) Класс Land ДОЛЖЕН иметь метод setGun (я объявил метод заполнителя в классе просто для большей уверенности в том, что это связано с автоматически сгенерированным кодом CoreData).
Мой код для класса Land приведен ниже:
import Foundation
import CoreData
@objc(Land)
class Land : NSManagedObject, Equipment {
var type = EquipmentType.LAND
enum CodingKeys: String, CodingKey {
case id
case name
case desc = "description"
case groupIconUrl
case individualIconUrl
case photoUrl
case primaryWeapon
case secondaryWeapon
case atgm
case armor
case speed
case auto
case weight
}
required convenience init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[CodingUserInfoKey.context!] as? NSManagedObjectContext else { fatalError() }
guard let entity = NSEntityDescription.entity(forEntityName: "Land", in: context) else { fatalError() }
self.init(entity: entity, insertInto: context)
let container = try! decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int64.self, forKey: .id)
self.name = try container.decodeIfPresent(String.self, forKey: .name)
self.desc = try container.decodeIfPresent(String.self, forKey: .desc)
self.groupIconUrl = try container.decodeIfPresent(String.self, forKey: .groupIconUrl)
self.individualIconUrl = try container.decodeIfPresent(String.self, forKey: .individualIconUrl)
self.photoUrl = try container.decodeIfPresent(String.self, forKey: .photoUrl)
self.primaryWeapon = try container.decodeIfPresent(Gun.self, forKey: .primaryWeapon)
self.secondaryWeapon = try container.decodeIfPresent(Gun.self, forKey: .secondaryWeapon)
self.atgm = try container.decodeIfPresent(Gun.self, forKey: .atgm)
self.armor = try container.decode(Int64.self, forKey: .armor)
self.speed = try container.decode(Int64.self, forKey: .speed)
self.auto = try container.decode(Int64.self, forKey: .auto)
self.weight = try container.decode(Int64.self, forKey: .weight)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
try container.encode(desc, forKey: .desc)
try container.encode(groupIconUrl, forKey: .groupIconUrl)
try container.encode(individualIconUrl, forKey: .individualIconUrl)
try container.encode(photoUrl, forKey: .photoUrl)
try container.encode(primaryWeapon, forKey: .primaryWeapon)
try container.encode(secondaryWeapon, forKey: .secondaryWeapon)
try container.encode(atgm, forKey: .atgm)
try container.encode(armor, forKey: .armor)
try container.encode(speed, forKey: .speed)
try container.encode(auto, forKey: .auto)
try container.encode(weight, forKey: .weight)
}
public func setGun(gun: Gun){}
}
Моя модель данных CoreData также показана ниже:
Наконец, если всего этого недостаточно для диагностики неисправности, вы можете клонировать репозиторий и запускать его локально из следующего общедоступного репозитория github: https://github.com/jamesjmtaylor/weg-ios