I have an entity object Country with country name and country code. It is a subclass of NSManagedObject and I am using it with core data model to store its value to a persistent store.
I have a place where the same Country object will used as a normal object i.e. I will use it to store some temporary country name.
For that I have initialized the Country as following
[NSManagedObject alloc] init]
Initialization successfully done, but I am not able to set any property to that object.
Hence I did an exploration. In that I found that, init for the NSManagedObject is not supported as per the documentation.
I don't know how to use the NSManagedObject Country with CoreData as well as a normal Object.
2nd paragraph of the NSManagedObject class documentation's overview:
A managed object is associated with an
entity description (an instance of
NSEntityDescription) that provides
metadata about the object (including
the name of the entity that the object
represents and the names of its
attributes and relationships) and with
a managed object context that tracks
changes to the object graph. It is
important that a managed object is
properly configured for use with Core
Data. If you instantiate a managed
object directly, you must call the
designated initializer
(initWithEntity:insertIntoManagedObjectContext:).
From the documentation of the method:
Important: This method is the
designated initializer for
NSManagedObject. You should not
initialize a managed object simply by
sending it init.
The documentation is actually very good.
You do not want to try to use an NSManagedObject outside of a viable CoreData stack. NSManagedObjects are quite explicitly designed to work within a correctly configured Core Data environment. If you need a temporary instance, you can either create an in-memory store or create one in your regular store and just don't save the changes without deleting it first.
Use initWithEntity:insertIntoManagedObjectContext: and pass nil for managed object context.
Related
I've searched all over StackOverflow already and it seems there are a few posts on this topic but either they are outdated or the solutions don't actually address the problem specifically.
I have a custom class called ProductDataModel. Then I have an array of these custom class objects of ProductDataModel. I want to save this array to coreData as an attribute. I have it set to the type of Transformable, but when I try to save it, the program crashes.
How do I save an array of custom objects to a core data property?
I have already made the class model inherit from NSObject.
I need to send an object (NSManagedObject (NSMO) subclass) up to a web service and retrieve it later. I was hoping I could somehow serialise it, but I'm hoping not to have to jump through the encoding hoops.
I can convert a simple NSMO object into a dictionary using:
[instance dictionaryWithValuesForKeys:instance.entity.attributesByName.allKeys];
However, my NSMO is a number of levels deep in terms of relationships to other NSMOs. What would be the best way to create a full serialised version of the object?
If you want to do this in a general way, you could write a recursive method serializedDictionary (either in a subclass of NSManagedObject or in a category) which:
Creates an empty NSMutableDictionary.
For each property, adds the key and value to the dictionary.
For each relationship, adds the relationship name as key and then calls serializedDictionary on the object and adds that as the value. If it's a to-many relationship, you'll have to put those values in an NSArray.
Note that if it's at all possible for a child object to be related back up to a parent (which is very possible if you have inverse relationships like Core Data recommends) you will either need to whitelist the relationships you save (easier) or pass along a set to keep track of which objects have already been serialized, so you don't encode them again (harder, I don't recommend this).
Why would I need to use a primitive accessor methods in a core data project?
I'm reading about Core Data and note the below:
By default, Core Data dynamically
creates efficient public and primitive
get and set accessor methods for
modeled properties (attributes and
relationships) of managed object
classes...
For example, given an entity with an
attribute firstName, Core Data
automatically generates firstName,
setFirstName:, primitiveFirstName, and
setPrimitiveFirstName:.
I'm still not sure what the primitive accessor methods are? How do they work? When & why would I need to use them over the normal accessor methods?
thanks
In normal classes, you would not usually use primitive accessors, but Core Data uses them frequently. The most common scenario: You write a custom accessor (to perform maintenance, create a default object, handle transient wrapper of persistent property, etc.) but want to use Core Data's optimized storage. If the optimized accessors were normal accessors, your custom one would prevent it from being available, but instead you just have to use the primitive accessor.
Also, the default accessors you get from Xcode include methods to add or remove objects from to-many relationships. If these methods used normal accessors, the normal accessors would trigger change notifications for the entire set. Instead they use the primitive accessors and create their own change notifications for just the part they are changing.
The most important thing is that the primitive accessors are the only way to get to the optimized storage. Without them, you would have to use instance variables, which Apple advises against.
If you are writing your own methods in a subclass of NSManagedObject, the primitive accessors enable you to get directly at the data the object contains.
Effectively, you would use them the same way you would use an instance variable in a normal class.
The primary use of primitive accessors is to prevent key-value observing notifications from being sent when you change a value. Sometimes you do not want such notifications sent because they have quite a bit of overhead. E.g. when importing large sets of data or when you use a transitory value to alter a persisted value.
You use them almost always when writing customer accessor methods. If you look at the accessor methods generated by Xcode for managed object subclasses, you can see how they are used.
I am trying to add objects to a persistent store in Core Data.
When the user taps the save button I initialize a new object which is a subclass of the NSManagedObject class and in the data model.
Profile *newProfile = [[Profile alloc] initWithEntity:[NSEntityDescription entityForName:#"Profile" inManagedObjectContext:MOC] insertIntoManagedObjectContext:MOC];
[newProfile setValue:userName.text forKey:#"userName"];
[newProfile setValue:txtInstitution.text forKey:#"institution"];
I can verify in the console that the values for userName and txtInstitution are correct and what expected, and also that the object has the proper attributes. However, it seems to save the object with the same values as whatever the first object saved was. Only one profile is created at a time, and the MOC is saved after each profile is added in this way.
Also, when a table tries to populate with data from the persistent store it will create rows as though are as many objects in the store as I have created at that time, but they will all have the same values.
Are you sure you are retrieving the objects from the store correctly? This sounds like it might be an issue with the fetch request you use to get the data out of the store and/or an issue with the way you display the data.
Is there any particular reason you're not using the designated initialiser for NSManagedObjects?
- (id)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)context
So you should use:
Profile *newProfile = [NSEntityDescription insertNewObjectForEntityForName:#"Profile" inManagedObjectContext:self.MOC];
Also make sure you are accessing your MOC via its property (self.MOC, not the ivar directly) as if you are using the templates provided by Apple you will notice the MOC is lazily loaded via its getter method.
I have an entity in core data called Location. Inside this I have a few fields, such as date. But, I would also like to save a class object in it that I created called Annotation. What type of attribute would I use for this, since it is a custom class object that I created?
Location (object)
|__ Date
|__ Annotation (MKAnnotation protocol)
You have two options:
If your Annotation class conforms to the NSCoding protocol (or if you're willing to write an NSValueTransformer to convert your custom class to an NSData instance, you can use a transformable attribute in your Core Data entity. Core Data will use the designated NSValueTransformer to automatically serialize/deserialize your Annotation instance for you.
You can create an Annotation entity in your Core Data model. You'll have to write your own code to assign a CLLocationCoordinate2D to the entity. You would probably create a persistent backing using two doubles and then write setters/accessors for the CLLocationCoordinate2D.
The advantage of (1) is that it's easier (if your class conforms to NSCoding). The advantage of (2) is that you can query against the data within the entity, even if using SQLite persistent stores. If you use (1), the data is opaque to the SQLite query engine, so you won't be able to query against it with a SQLite backend.
it would be easier to add the class as a core data class then you could just have a relationship between the two classes as a one-to-one relation. you can however use the type binary data as an attribute type and store whatever data you want in there. ( i use this to store c structs sometimes ) You just need to use the NSData class to wrap your object and set the property.