Add an array of custom objects to Core Data - swift

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.

Related

Saving a Set into Core Data

Hi I'm currently trying to set up core data in my project after previously using NSCoding.
I have the problem that I can't save a Set into Core Data. I've looked for days on ways to convert it to Binary data in Swift and saving that but I can't seem to find anything.
The set contains elements of a custom object I made.
PS: If possible, also, how would a generic be saved into Core Data?
Swift sets are bridged to the foundation class NSSet, and NSSet conforms to the NSCoding protocol. That means you can save a set as an attribute of a managed object if you
Treat the set as an NSSet (if it's not one already, use mySet as NSSet)
Adopt NSCoding on your custom objects in the set
Make the Core Data attribute type "transformable"
If you do all that, Core Data will automatically invoke NSCoding methods on the set, which will in turn invoke the same methods on your custom objects. You'll just assign the set to the attribute, and Core Data will do the rest.

Transformable Collection in Core Data with custom Objects

I have to store a collection of custom objects (Dictonary) in Core Data Database.
So far so good. The Dictonary is stored and can be loaded without problems as a "Transformable" object.
The custom Object holds properties, but these are nil after loading them from the Database.
After searching a lot, I haven't found anything for this problem.
It seems that the properties are not getting stored in this way. (Maybe because only the address is stored and not the data??)
Sure it would be better to store an object of Core Data supported datatypes, but in this case the transformable Object is just fine and saves me a lot work and time.
Thank U!
The whole idea of transformable objects is covered in the Core Data Guide. Note that this uses a keyed archiver / unarchiver to create a NSData object from your object or the reverse. This means your customer objects my adhere to NSCoding, and encode all the information in them when asked to as well as handle unencoding.
If your are not doing this now this is the root cause of your problem. What I suggest you do is adopt NSCoding in one custom object, then verify that in fact you can encode it to a NSData object, then from the object unencode it and get the same object back. When you have that working you can then test with Core Data.

Can I serialise a NSManagedObject?

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).

Sample code illustrating MVC architecture in iOS

I'm trying to get the hang of MVC architecture. Say I have a plist in which there are a list of persons and each person has a few attributes like name, address and photograph. Suppose
I want to display these details in a table view. The cell title would be the name, description would be the address and the image towards the left would be the photograph of the person.
One approach I could take is to load the plist in an array-of-dictionaries in my viewDidLoad: and then display them.
However, I want to adopt an Object Oriented method by creating 'Person' class. How do I go about doing the same in this case? I believe I could start by creating a 'Person' class with three attributes:Name, Address, Photograph. What next? I would need many instances of this 'Person' class right? How would I 'load' each instance with a corresponding Person entry from the plist? Should I create another class that does this 'loading'? Do people use Singleton class to achieve his?
Could someone share some sample sample code to illustrate this? Or maybe guide me to blogs/resources that talk about this?
Hmmm, I think you are over thinking this a bit. I would just create a class that would handle my person, in this case your 'Person' class.
I would simply store each person using Core Data. Then, when it's time to display them, I would just make a fetch request and store all person managed objects into an NSMutableArray (which simply handles arrays of objects). Then you can simply use the index value to display the numerous persons in your array in a tableView.
In summary I would:
1. For every person, create instance of Person.
2. Verify if person exists in my Core Data Person Entity.
3. If not, then insert into Core Data (the object will become an
NSManagedObject).
4. For displaying, simply do a fetch request to pull all persons in your
entity. Here I prefer to store the
results into an NSMutableArray, but
that is completely up to you. Make
sure you release your fetch request
after the results are store in the
array.
5. Reference them to your table view using the index value for each
person NSManagedObject in the array.
For something that doesn't involve storing simply:
1. Create instance of Person for every entry.
2. Add Person object to array.
3. Reference each Person to table view using index value.
In the end the approach that you take will be dictated by what you want to do with the information.
As for reading the plist, I would opt for reading an XML for which all you need is an XML Parser class (there are several options for parsers). Since I don't do anything but parse the XML, I use NSXMLParser, but that choice is also up to you. Just create an NSXMLParser class (make sure that the different actions for when the parser finds a given element are in play inside that parser). So yes, you would need to make additions to the NSXMLParser for handling each element. It's really easier than it sounds.
Also, by storing in Core Data, you can always fetch the info without you using a Singleton.
I believe you are not looking for a design solution to the above mentioned question. If that is the case #A Salcedo 's version looks fine.
if you are looking for general guide lines for MVC and modeling , Martin Fowler's site offers some of the best (agile) design/modeling guidelines.
http://www.martinfowler.com/eaaDev/uiArchs.html (on MVC) and
http://martinfowler.com/design.html (many interesting design related posts).
Happy reading.

NSManagedObject subclass outside of managed object as a normal object

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.