I got this error message when I tried to save the data to core data. I think it got maybe something to do that some of the attributes in my Entities are of type Transformable.
Error Message:
[error] error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x60000029c8f0> , Object of class Address is not among allowed top level class list (
NSArray,
NSDictionary,
NSSet,
NSString,
NSNumber,
NSDate,
NSData,
NSURL,
NSUUID,
NSNull
) with userInfo of (null)
Entities and their attributes in the .xcdatamodeld file (screenshots):
User Class UPDATED:
@objc(User)
public class User: NSManagedObject, Decodable {
private enum CodingKeys: String, CodingKey { case address, company , avatar, email, id, name, phone, username, website }
required convenience public init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError("NSManagedObjectContext is missing") }
let entity = NSEntityDescription.entity(forEntityName: "User", in: context)!
self.init(entity: entity, insertInto: context)
let values = try decoder.container(keyedBy: CodingKeys.self)
address = try values.decode(Address.self, forKey: .address)
avatar = try values.decode(String.self, forKey: .avatar)
company = try values.decode(Company.self, forKey: .company)
email = try values.decode(String.self, forKey: .email)
id = try values.decode(Int32.self, forKey: .id)
name = try values.decode(String.self, forKey: .name)
phone = try values.decode(String.self, forKey: .phone)
username = try values.decode(String.self, forKey: .username)
website = try values.decode(String.self, forKey: .website)
}
}
Address Class UPDATED::
@objc(Address)
public class Address: NSManagedObject, Decodable {
private enum CodingKeys: String, CodingKey { case geo, city, street, suite, zipcode }
required convenience public init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError("NSManagedObjectContext is missing") }
let entity = NSEntityDescription.entity(forEntityName: "Address", in: context)!
self.init(entity: entity, insertInto: context)
let values = try decoder.container(keyedBy: CodingKeys.self)
street = try values.decode(String.self, forKey: .street)
suite = try values.decode(String.self, forKey: .suite)
city = try values.decode(String.self, forKey: .city)
zipcode = try values.decode(String.self, forKey: .zipcode)
geo = try values.decode(Geo.self, forKey: .geo)
}
}
Address Class UPDATED:
extension Address {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Address> {
return NSFetchRequest<Address>(entityName: "Address")
}
@NSManaged public var city: String
@NSManaged public var street: String
@NSManaged public var suite: String
@NSManaged public var zipcode: String
@NSManaged public var geo: Geo
}
All suggestions and code samples are appreciated. Thanks. :)
Your Core Data model is wrong.
Delete the attributes address
and company
. Both must be relationships.
User
, click on the + sign below relationship, name it address
, select Address
as destination.Address
, click on the + sign below relationship, name it user
, select User
as destination and address
as inverse.User
and select user
as inverse of the relationship.Make sure that both relationships are to-one and that both @NSManaged objects are declared in the classes.
Do the same for Company
and for the other wrong Transformable attributes.
And in init(from decoder
you have to set one direction of the relationships explicitly.