Are ivars of PFObject subclasses stored in local datastore? - ios

I have a subclass of PFObject called Session. This object stores an array of objects as an instance variable. The array contains objects of type Event, which is also a subclass of PFObject. When I call the pinInBackground on the Session object to cache it locally, will this array instance var also get cached? I understand that caching standard PFObjects stores the data dictionary, but what about subclasses?

Based on the comment from #lightice11 above, I realized that this can be achieved by marking instance vars as #NSManaged, and they will be saved in the Parse Local Datastore.

Make sure you've added the #NSManaged tag to the variable.
Parse will then automatically save changes to the variable, but it does not have a default value. This can be solved in many ways, some of which I outlined here.

Related

Best way to save a dictionary containing bunch of Core Data objects?

I wish to save a dictionary containing some Core Data objects (bunch of different entities). The objects also have quite a few relationships (and inverse relationships) defined. What would be the best way to go about it?
I tried using NSKeyedArchiver and writing to a file. While that works great, when trying to read from the file using NSKeyedUnarchiver, it fails on one of the classes with the error
-[SomeEntity initWithCoder:]: unrecognized selector sent to instance
EDIT - More details
I have a bunch of objects, each having properties based on which they can be filtered. The properties are in themselves Core Data entity objects since they have a complex structure.
I wish to save the filters the user has selected so that the next time they view the objects, the objects can be filtered as per their previous selection.
Say there are 3 filters, Filter A, B and C and each can have 5 different values. Now the user might select Filter A1, A2, B1 and C3 (or a different combination). My question, how do I save these selected filters (A1, A2, B1 and C3 in this case) using Core Data?
Let me see if I understand your question: You have a collection of managedObjects that are already saved in a context. They may already be persisted in the SQL database. You want to save that collection ALSO to another file for other purposes. You have already considered saving the information of this collection inside core-data in some way and have already rejected it. You have also considered simply saving the query generation tokens to save the state of the database as it currently is, but that also is not what you want. The point is to have a file that contains a copy of some of the managedObjects organized in a way that you can get the data back without using the SQL database that was already designed exactly for that purpose.
Solution 1: Turn each managed object in a dictionary.
You can get every attribute and every property of every object by getting a managed object's entity and then accessing the attributesByName and
relationshipsByName property of the entity. From there you make a simple loop to put each property into a dictionary. I also suggest you store the objectID and point to the objectID when encoding the relationships. Then replace the managedObject in your dictionary with dictionary that contains all the attributes and relationship. This new dictionary should be easy to archive and unarchive.
This make sure that the data when you unarchive is exactly how you left it. When you unarchive you will get a COPY of data and if the managed objects have changed in your database since then, you will get the OLD values. Also these copies are not core-data object because they are unconnected to a managed Object Context.
Solution 2: Just save the Managed Object's ObjectId.
Replace every managed object in your collection with the object's objectId. This dictionary can be easily archived. When you unarchive it replace every objectId with a core data object (if found) using existingObjectWithID: on the context. If entities have been deleted then you won't get them back. If entities have changed then you will get the NEW values.
Solution 3: Don't do any of this
It seems to me that you may not be aware core-data are already saved in a database. If you have some collection of managedObjects, you should be able to recreated it from your database. If you aren't able to, then you should add properties and/or relationships that will allow you to so.
Try like this :
ARCHIVE :
NSDictionary *yourDictData = [NSDictionary dictionaryWithObject:json forKey:#"key"]; // This is for example. Here you have to replace ur dictionary
NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:yourDictData];
UNARCHIVE :
NSDictionary *myData = [NSKeyedUnarchiver unarchiveObjectWithData:yourDictData];

Realm inverse relationship returns object with nil properties

I got a class named Team, it has a RLMArray property called players with Player class objects.
When i try to access the team by calling (according to documentation)
[self linkingObjectsOfClass:#"Team" forProperty:#"players"];
on a player object, i get a single team object ( how it's supposed to be ), but all the properties are nil, even primary key.
Has anyone faced the same issue?
It's expected that instance variables of persisted RLMObject instances will be nil as the property getters read values directly from the Realm file. The instance variables are only used for objects prior to being saved to the Realm, and remain nil after that point.
The Debugging section of the Realm documentation touches on this topic and mentions an LLDB script that can be used to show property values of persisted objects when debugging in Xcode. The -description method on the model classes, used by NSLog when formatting objects using the %# format specifier, will also show the property values as expected.

Exclude PFObject Sublclass' Attribute to Get Persisted

I'm working on an iOS app using the native Objective-C Parse API, and I have a subclass of PFObject called MRPlace which has a number of attributes that will be stored in the parse back-end. However, there is an attribute (Say the attribute is called isFavorite) that I would only like to be kept locally (client-side) and thus excluded from being persisted in the database.
I've looked through the documentation and the web with no luck. How can this be accomplished?
As mentioned in knshn's comment, using #synthesize isFavorite = _isFavorite for example will work.
Since they won't be stored on Parse, and really won't even be persisted locally (with no Local Data Store,) you should store these values elsewhere. There's no way to specify local-only keys on a PFObject.
I found a way to accomplish this in swift so I thought I'd share. Say there's an attribute called streetName. This is how you'd declare it normally:
#NSManaged var streetName: String
However, if you omit the #NSManaged it works as desired!
var streetName: String

NSManagedObject changedValues ignoring string value

I have a subclass of NSManagedObject on which there's a "currency" attribute. This attribute is a 3 letters string. When I change it from "USD" to "CAD", and then call changedValues on the object, changedValues returns an empty dictionary. Is that the normal behaviour?
I save the managedObjectContext first, then change the attribute, then call changedValues.
This attribute is: not transient, optional, not indexed, no default value.
EDIT: Thx for the help guys I found a bug in my code. Now it works just fine.
I found a bug in my code. Now it works just fine. ;)
I was using a delegate method to update the object from another viewController. When coming back from that viewController I saved the managedObjectContext in viewWillAppear which basically erased the changedValues.
Do it before you save the context.
NSManagedObject Class Reference
changedValues
Returns a dictionary containing the keys and (new) values of
persistent properties that have been changed since last fetching or
saving the receiver.

How to override hash and isEqual for NSManagedObjects?

We have a bunch of NSManagedObjects of various types.
Some of them have members that are NSSet's of other NSManagedObjects.
The problem is that I really need to override the hash and isEquals methods of the objects that are IN the set - but they are NSManagedObjects.
I'm having problems with getting multiple identical objects in the set.
As far as I can tell, since hash defaults to the object address - all objects are different. So I need to override hash and isEquals - but can't see any way to do it.
What we have is a bunch of stuff in the System, and more comes in via XML - sometimes repeats of the existing objects. When they are the same, I don't want dups added to the set.
As mentioned above by Wain, NSManagedObject documentation states that you must not override hash or isEqual:. So this means a stock NSSet does not do what you need.
Some of your options are:
Enumerate the NSSet contents to identify and remove duplicates
Write a factory method for your NSManagedObjects that will return the same object when given the same inputs
Fix the XML to not include duplicated objects
Unique the objects coming from the XML before they become NSManagedObjects
Modify the input XML to include a unique identifier that you can track, assuming the duplicated objects are exact duplicates
Implement your own NSSet-like collection class that performs a different uniquing test than hash and isEqual:

Resources