Fetching entities in CoreData causing a crash

Fetching entities in CoreData causing a crash



I have a model which looks like this and contains NSManagedObject properties, namely the blendsWith property which is a type of [Tag]:


blendsWith


[Tag]


extension Oil

@nonobjc public class func fetchRequest() -> NSFetchRequest<Oil>
return NSFetchRequest<Oil>(entityName: "Oil")


@NSManaged public var blendsWith: [Tag]?
@NSManaged public var color: String?
@NSManaged public var commentsCount: Int64
@NSManaged public var id: Int64
@NSManaged public var imageURL: String?
@NSManaged public var latinName: String?
@NSManaged public var name: String?
@NSManaged public var properties: NSObject?
@NSManaged public var research: String?
@NSManaged public var resourceType: String?
@NSManaged public var viewsCount: Int64



public class Oil: NSManagedObject, Codable

enum CodingKeys: String, CodingKey
case resourceType = "resource_type"
case id, name
case imageURL = "image_url"
case color
case latinName = "latin_name"
case emotions
case safetyInformation = "safety_information"
case fact, research
case viewsCount = "views_count"
case commentsCount = "comments_count"
case blendsWith = "blends_with"
case foundInBlends = "found_in_blends"
case properties
case sourcingMethods = "sourcing_methods"
case usages


required convenience public init(from decoder: Decoder) throws
let context = CoreDataHelper.sharedInstance.persistentContainer.viewContext
guard let entity = NSEntityDescription.entity(forEntityName: "Oil", in: context) else fatalError()

self.init(entity: entity, insertInto: context)

let container = try decoder.container(keyedBy: CodingKeys.self)
self.resourceType = try! container.decodeIfPresent(String.self, forKey: .resourceType)!
self.id = try! container.decodeIfPresent(Int64.self, forKey: .id)!
self.name = try! container.decodeIfPresent(String.self, forKey: .name)!
self.imageURL = try! container.decodeIfPresent(String.self, forKey: .imageURL)!
self.color = try! container.decodeIfPresent(String.self, forKey: .color)!
self.viewsCount = try! container.decodeIfPresent(Int64.self, forKey: .viewsCount)!
self.viewsCount = try! container.decodeIfPresent(Int64.self, forKey: .viewsCount)!
self.commentsCount = try! container.decodeIfPresent(Int64.self, forKey: .commentsCount)!
self.latinName = try! container.decodeIfPresent(String.self, forKey: .latinName)!

if let blendsWith = try container.decodeIfPresent([Tag].self, forKey: CodingKeys.blendsWith)
self.blendsWith = blendsWith



public func encode(to encoder: Encoder) throws






Tag looks like this:


Tag


extension Tag

@nonobjc public class func fetchRequest() -> NSFetchRequest<Tag>
return NSFetchRequest<Tag>(entityName: "Tag")


@NSManaged public var id: Int64
@NSManaged public var name: String?
@NSManaged public var resourceType: String?
@NSManaged public var tagType: String?
@NSManaged public var viewsCount: Int64



public class Tag: NSManagedObject, Codable

enum CodingKeys: String, CodingKey
case resourceType = "resource_type"
case id, name
case viewsCount = "views_count"
case tagType = "tag_type"


required convenience public init(from decoder: Decoder) throws
let context = CoreDataHelper.sharedInstance.persistentContainer.viewContext
guard let entity = NSEntityDescription.entity(forEntityName: "Tag", in: context) else fatalError()

self.init(entity: entity, insertInto: context)

let container = try decoder.container(keyedBy: CodingKeys.self)

self.resourceType = try! container.decodeIfPresent(String.self, forKey: .resourceType)!
self.id = try! container.decodeIfPresent(Int64.self, forKey: .id)!
self.name = try! container.decodeIfPresent(String.self, forKey: .name)!
if let viewsCount = try container.decodeIfPresent(Int64.self, forKey: .viewsCount)
self.viewsCount = viewsCount
else
self.viewsCount = 0

if let tagType = try container.decodeIfPresent(String.self, forKey: .tagType)
self.tagType = tagType
else
self.tagType = "lol"



public func encode(to encoder: Encoder) throws






When I go to fetch the Oil data stored locally, I get this crash:


Oil


2018-08-29 20:31:30.602764+0100 EL[27994:14799374] -[EL.Tag initWithCoder:]: unrecognized selector sent to instance 0x60c000679980
2018-08-29 20:31:30.603905+0100 EL[27994:14799374] [error] error: exception handling request: <NSSQLFetchRequestContext: 0x608000181ee0> , -[EL.Tag initWithCoder:]: unrecognized selector sent to instance 0x60c000679980 with userInfo of (null)
CoreData: error: exception handling request: <NSSQLFetchRequestContext: 0x608000181ee0> , -[EL.Tag initWithCoder:]: unrecognized selector sent to instance 0x60c000679980 with userInfo of (null)
2018-08-29 20:31:30.612185+0100 EL[27994:14799374] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[EL initWithCoder:]: unrecognized selector sent to instance 0x60c000679980'



What could be causing this crash?



For reference, my fetching method looks like this:


func getItems<T : NSManagedObject>(predicate : NSPredicate? = nil) -> [T]
do
let reqest = T.fetchRequest()
reqest.predicate = predicate
if let items = try persistentContainer.viewContext.fetch(reqest) as? [T]
return items
else
return [T]()

catch let error as NSError
print("Could not fetch. (error), (error.userInfo)")
return [T]()




And works like this:


let arrat : [Oil] = CoreDataHelper.sharedInstance.getItems()





Are you calling NSKeyedUnArchiver somewhere?
– vadian
Aug 29 at 19:58


NSKeyedUnArchiver





No I am not. Should I be?
– spogebob92
Aug 29 at 20:01





No, you shouldn't. NSKeyedUnArchiver calls initWithCoder which is a part of the error message.
– vadian
Aug 29 at 20:03



NSKeyedUnArchiver


initWithCoder





Is Oil.blendswith an NSSet, an NSOrderedSet or Transformable([Tag])?
– Fabian
Aug 29 at 21:08



Oil.blendswith


NSSet


NSOrderedSet





a Transformable([Tag])
– spogebob92
Aug 29 at 21:09




2 Answers
2



If you debug this code does it ever step into the Tag init function? It appears the compiler is not seeing your Tag.init function which is most likely due to your Data Model for the Oil object not correctly setting the class type of the blendsWith property.


init


blendsWith



Check your data model for Oil and make sure that blendsWith is set to the correct type of Tag.


blendsWith



EDIT:
For Core Data to pick up your class setting you might need to add the objc flag before your class definition:


objc


@objc(Tag)
public class Tag ...





It does hit the breakpoint within the init function
– spogebob92
Aug 29 at 20:46


init





Can you verify that your data model sets the blendsWith array in the Oil entity with the correct Tag class?
– davidethell
Aug 29 at 20:51





Also check my edit about adding the objc flag before your class declaration.
– davidethell
Aug 29 at 20:55


objc





Can confirm its correct and the Objc flag doesn't fix the problem. Thanks for the help though.
– spogebob92
Aug 29 at 21:10





When you confirmed it was hitting the breakpoint I didn't think the objc flag was going to help, but it was worth a shot. It does appear iOS is correctly seeing your class assignment.
– davidethell
Aug 29 at 21:55



A Transformable is usually coded by CoreData to Data (stored just as that), and coding an NSManagedObject may do things you do not expect. Decoding it could make things „more“ unexpected. (Coding done by NSKeyedArchiver and NSKeyedUnarchiver automatically on assignment/use.)


Transformable


Data


NSManagedObject


NSKeyedArchiver


NSKeyedUnarchiver



If you want to use Transformable then making it an NSManagedObject is pointless due to the argument above. (I at least have no experience with it, and have not heard what use it would have.)


Transformable


NSManagedObject



So its usually Transformable OR CoreData-relationships(with NSManagedObjects) to model one relationship in CoreData, but not both to model a single one.


Transformable


CoreData-relationships


NSManagedObject



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)