2
votes

I'm trying to make a weather app in Swift that will save the cities I add to Core Data, each city contain a weather object that is also saved to Core Data and other various variables.

But I soon figured out, using Core Data NSManagedObjects subclasses outside a Core Data context is close to impossible (dealing with NSNumber and similar, no custom init, forced to save them somewhere, what if I stop using Core Data tomorrow, ...).

So what's the best practice to keep using Core Data but also use models outside of its context?

My solution right now is to create a Class for each Model, so :

class City
{
    var country: String?
    var name: String?
    // ...
}

Is the corresponding class of :

class CD_City
{
    @NSManaged var country: String?
    @NSManaged var name: String?
    // ...
}

So I can use City anywhere and anyhow I want. But I need a func to turn a City into CD_City and opposite. So I'm really not sure I'm doing it the best way. Also what would you recommend as a conversion method ?

(FYI I'm using MagicalRecord as a Core Data helper)

2

2 Answers

4
votes

TL;DR - Don't do that or things will break.

There used to be various hacks for getting it to sort of work, but they all rely on undocumented behavior in CoreData. I would never use anything like that in code I wanted to show another human being, much less ship to customers. CoreData needs to insert proxy objects that hook into property change events on your model objects, and the only way it can reliably do that and track the original data values were is if it is responsible for creating those entities in the first place; That also makes the faulting & uniquing system work. Don't think of Core Data as an ORM, it really is an object graph management framework, and as such it is designed to be used a certain way with no easy solution to side step it safely.

2
votes

If you don't want to save an NSManagedObject or a subclass of it, then you can create it with

init(entity entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?)

and pass nil for insertIntoManagedObjectContext this will create you an instance but it will be not be saved to the MOC.

In case you have to save it to the MOC later, you can use NSMangedObjectContext's

func insertObject(_ object: NSManagedObject)