I'm learning Core Data and I understand all the examples for creating a brand-new object, assigning values and saving it to the managedContext (insertNewObjectForEntityForName).
However, what if I've already created an object elsewhere (model Category)? In this case I'd want to just assign the current Context to this Model, and then save it.
What is the command/approach to take an in-memory Model, and then assign to a context so it can be saved?
If you want to use Core Data to manage your data, you'll need to:
create an appropriate model description (.xcdatamodeld file)
modify your model class(es) so that they inherit from NSManagedObject
set the "Class" for each entity in your model description to one of your NSManagedObject subclasses
add code to your app to create and manage the Core Data stack, fetch data, etc.
This is all very do-able, but I wouldn't recommend that you attempt it until you have a solid understanding of Core Data and your reasons for adopting it in your project. The lack of clarity in your question may indicate that you're not quite there yet; you might benefit from working on a small project that uses Core Data from the start.
If all you want to do is to save your data, you should know that Core Data is not the only way to do that. A much simpler approach to saving your data would be to adopt the NSCoding protocol in your data model and then use a NSKeyedArchiver to store your data. Get the full story from the Archives and Serializations Programming Guide. There are other ways to do it as well, but NSKeyedArchiver is a good place to start.
You can only save NSManagedObjects (and their subclasses) to CoreData. NSManagesObject can not be created except in the context of an NSManagedObjectContext.
So, what you're saying is confusing. Do you have a non-CoreData model object?
Related
I need to be able to create new core data entities during runtime. I've written the code to create the objects programmatically, however, I can't add the entities during runtime as the model is immutable.
My problem is similar to this post, however there is no satisfactory answer: How to dyanmic create a new entity (table) via CoreData model?
The documentation regarding changing the core data model explains:
Managed object models are editable until they are used by an object
graph manager (a managed object context or a persistent store
coordinator). This allows you to create or modify them dynamically.
However, once a model is being used, it must not be changed. This is
enforced at runtime—when the object manager first fetches data using a
model, the whole of that model becomes uneditable. Any attempt to
mutate a model or any of its sub-objects after that point causes an
exception to be thrown. If you need to modify a model that is in use,
create a copy, modify the copy, and then discard the objects with the
old model.
However, I'm unclear on what exactly this is saying--that the whole core data model can't be changed once the persistent store coordinator has been used or the attributes/etc of the individual entities can't be changed.
To be clear, I do not want to change the attributes of my current entities, I simply want to add new entities. It just seems weird to me to have to use migration to add new entities.
Any thoughts?
Thanks!
The documentation is pretty clear.
Copy the model.
Apply your changes to the new copy.
Destroy your old MOC, Persistent Store Coordinator, and all objects created from those.
Apply a migration, if necessary.
Create a new Core Data Stack (MOC, PSC, etc) using your updated model.
The migration could be a sticking point, but it should be do-able.
I am learning a bit on NSCoreData and before introducing it some existing projects I have, I would like to validate my good understanding of the core principles.
From what I have understood, NSCoreData make it easier to manage local storage of object (+retrieval after that) by subclassing our Model class from NSManagedObject rather than from NSObject.
Right ?
I have a few questions then. Let's consider I am building a real estate application with as core model object the class Property that can represent an appartment, a house, and all related information. Currently it is managed in my app as a subclass of NSObject.
1) I retrieve the properties from the server through a search query, and have written a initWithJson : method to populate each instance.
Now if I subclass Property from NSManagedObject, I will create my instances by using
+(id)insertNewObjectForEntityForName:(NSString *)entityName
inManagedObjectContext:(NSManagedObjectContext *)context
and I will be still be able to add a populateWithJson: to my class to fill in the properties.
Then I will create a lot of Property instances in the current managedObjectContext, and if I do a save, they will be stored at the physical layer.
If I call again the same webservice, and retrieve the same JSON content, I will recreate the identical managed objects.
How to avoid redundancy with the [managedObjectContext save:&error] call and not to store physically several time the representation of a single real life property ?
2) Let's say I want to store physically only some properties, for instance only the one the user want to have as favorites.
[managedObjectContext save:&error] will save all created / modified / deleted managed objects from the context to the physical layer, and not only the one I want.
How to achieve that ?
Am I supposed to declare another context (managedObjectContext2), move the instance I want to store in that context, and do the save in that one ?
(I mean, I will have a context just to manipulate the object, create instances from the JSON and represents them in UI ... and a second one to actually do the storage)
Or am I supposed to stores all the objects, and add a isFavorite BOOL property , and then fetching using a predicate on that property ?
3) The app has a common navigation pattern : the UITableView lists Properties instance with the minimum information required, and going on a detail view call a webservice to request more information on a specific Property instance (images, full text description).
Is it a good practice for instance to call the webservice only if the property.fullDescription is nil, and then update the object and store it locally with all detailed information, and the next time only to fetch it locally with a predicate on the property.id ?
What about object that might be updated server-side after they have been created?
Thanks for your lights
1) Retrieve the server data into a temporary form (array of dictionaries?), then for each possible property in the array, check to see if you already have an object in Core Data that matches. If you do, either ignore it or update any changed attributes; if not, create a Property object.
2) Decide which things you want to persist in order to support your app's functions. There's no point in creating a managed object for something you don't want to save. Note, though, that Core Data supports sub-classes if you want both Property and FavoriteProperty.
3) Entirely up to your "business rules"…. How often do you need local data to be updated? The only technical consideration might be the guideline to not keep large files locally that can be re-created on demand.
I'm devellopping an IOS app for one month and I feel like I'm ready to create the data base. So as I've learn at school, I took my pencil and start to create my data base design.
Then I start to read the core data guides, in fact I've already used core data but it was in smaller projects. So I read about the Managed Object and they seems to always fit exactly the model object (MVC) of the applications.
So this is my question. Does I have to write the Managed Objects as an sqlLite data base shema (with split tables etc...) and start to write some methods to construct my model objects from thoses tables ? OR should I write the managed object exaclty as the Model objects ? They will be reconstructed much easier but won't it be less efficient?
To ask it in an other way: do the core data base shema should looks like an sqlLit data base with split tables or should it looks like as a set of my Model Objects?
I hope my question is clear.
Thank you,
Alexandre
If you want to use core data, you should not, in any way interact with the SQLite database. The exact way core data stores the objects should be opaque to you.
There is nothing to stop you writing the database layer yourself. You can make and interact with an SQLite database directly and do everything yourself.
General advice is that core data has been around a long time and any issues you encounter making objects and keeping them in sync across threads, caching and speed of access have already been encountered and fixed by the core data team. Save yourself some work, Stand on the shoulders of giants and use Core Data.
Just because you have tagged your question with iOS, one of the best things you can do, is to forget about traditional model relationship techniques you have previously used in relational database (especially the one used with web applications), and structure your NSManagedObject graph depending also on the use you are doing in your UI.
This is especially true when you have something like UITableView. For example, if you are showing only title and description in a table cell, and then you have detail view with all the data, it has perfect sense to model your graph like this:
EntityMain {
NSString *title,
NSString *desc,
// other that may be useful, such as a state...ecc
toOne relationship --> EntityDesc
}
EntityDesc {
NSString *prop1,
NSString *prop2,
......
....
NSString *prop 20
}
Where EntityMain is retrieved, say, by a NSFetchedResultsController, while in the detail view you can retrieve the whole object. In this case you are not fetching more than necessary, and performance will benefit.
This will also help you in case you want to have a separated NSManagedObjectContext for detail editing.
I'm fairly new to iOS development, so I need some advise.
I'm working on a project (creating a character sheet app for an upcoming table top RPG), and I seem to have put the cart a bit before the horse.
I've already created a subclass of NSObject called characterClass that holds everything I need for a single instance of the character sheet. It also has methods to calculate derived information. I have 2 more classes storing abilities, and have them in NSArrays in the characterClass. Now that it's working, I need to work on data persistance, and storing/retrieving multiple characters.
I'm thinking, of using Core Data, creating a separate entity that matches my characterClass, and having a characterClass init method that pulls the data out of Core Data and puts it into the current instance of characterClass. That seems a bit obtuse to me, (implementing a class separate from the entity) but maybe it's a good way to do it.
I would eventually like to set up dropbox syncing for this information, so whatever I do I would like to have compatible with that. (Core Data with XML files as the backend?)
What would be the best method for something like this?
Rather than just pull the data out of Core Data and use it to create your character class, you could just tweak your character class so that it is an NSManagedObject subclass. That way you are storing your objects directly in Core Data
I have two NSManagedObject subclasses, Person and Photo, that I am storing with CoreData. I need a comment object for a photo, and I was wondering if I should create a new NSManagedObject subclass and store it in core data, or create a subclass of nsobject and have an array of those in my Photo object? Which is the best thing to do? What are the pros and cons of each one?
in my opinion, using Core Data is much better;
because you can use the relation to get the comment directly , and cache your comment in the database will release the time of request from the server~
If you have an array in Photo... Photo is a NSMagangedObject, so it would end up being store in core data if you want to keep them around. And that array would probably need to be converted in an NSValue...
Core Data is like a data base on many aspect, and in a data base you don't think arrays, you think tables.
So I strongly suggest NSManagedObject.
It would potentially allow you to query for all photos that have comments add or modified in a specific day. That thing would be extremely complicated to achieve with the array model you are proposing.