I'm about to implement a like functionality between a User entity and some other entity, such that User A can like an entity X. However, I'm not sure how to best implement this in Core Data.
There are two main points I need to consider:
Adding another likeable entity should be trivial
There needs to be a way to sync a Like that has been performed offline
My initial thought was to create an abstract Core Data entity Like.
A User has a to-many relationship with Like, and a Like has one User.
Then for each entity that should be likeable, I create a subclass of Like that has a to-one relationship to the likeable entity. The relationship to the User is inherited.
This way, the abstract entity Like can have attributes such as "syncedAt" and "deletedAt" so that it's possible to find out if a Like type entity has been synced to the server or not.
Does this sound reasonable or are there better ways to solve this problem in Core Data? Are there disadvantages to this design that I'm not foreseeing?
why not have a parent entity LikableEntity which your likable entityies inherit from: this could have the synchedAt attributes. The your User has a to-many relationship likedEntities which contains anything it has liked
Related
This is JSON response:
I have to store categories with childs in Core Data. Should I use Transformable type for childs?
Here, category and child classes are the same in Core data.
How can I do this? Any help?
Here is my Core data model structure:
One to many relationships is the answer you are looking for as they were made for this use case. The category entity will be the parent and the sub-Category entity will the child.
The parent category entity will have a to-many relationship with the subcategory entity, please make sure that you add an inverse relationship as well from the child to parent.
And what most devs forget about is the delete rule, do think about what should happen to the parent when a subcategory is deleted or when a category itself is deleted.
I am sharing some of the tutorials and I hope they are helpful
Core data delete rule: https://cocoacasts.com/core-data-relationships-and-delete-rules/
Core data one to many relationship: https://cocoacasts.com/one-to-many-and-many-to-many-core-data-relationships/
Recently, I am trying to refine my code. I found that all my entities has attributes named identifier and owner, so I want to create a entity to be their parent which contains identifier and owner.
Following is the result, all object inherit from a parent named SRModel, which has identifier and owner attributes.
However, after I delete all these redundant properties, the persistent store is not able to auto migration.
How can I solve the problem? Do I have to do migration by myself?
Are there any simple way to do so?
According to Apple's Core Data Model Versioning and Data Migration Programming Guide, you can't do that automatically.
You cannot, however, merge entity hierarchies; if two existing entities do not share a common parent in the source, they cannot share a common parent in the destination
Note Andy Riordan's point about inheritance. And don't just take his word for it; look at the generated .SQLite files yourself under the old and new models. Adding a parent entity with only two common attributes will just make your entities, and backing tables, larger, with no performance benefit. If you really want to note the two common elements, use a Protocol to call them out.
I've looked all over SO, youtube, and the Apple docs and am having real trouble understanding the distinction--if any--between parent/child and to-one/to-many inverse relationships in Core Data. Nothing I've found appears to address the subject directly and explicitly.
I need to know this because I want to load a table view with data from one entity, called ListActivity, grouped into sections defined by another entity called ListCategory, as shown here. Also not real confident of my naming convention:
Can someone please clearly explain the difference--and when to use each case--or point me to something that can?
Thanks!
Edit for clarification:
For comparison, here is a screenshot of my entities with ListCategory specified via the menu in the Data Model Inspector as the Parent Entity for ListActivity:
Relationship is used go down in an object graph (i.e activities in a category) while an inverse relationship is used to go up in an object graph (i.e category to which an activity belong to).
While naming convention looks fine. better use "activities" instead of "listActivities" and "category" instead of "toCategory".
Generate classes for them and you'll better know how these will work out.
I am using coredata to save the server data through web services in my application and I am storing relationships as an object to the entity.
I have many entities e.g "Inspirations" and "Products" and both are related to each other. I have a problem whenever the records are updated in the third entity which is "Filters" then the relations of the entities broke and I cannot apply filters on the entities.
[object addRelatedInspirationsObject:related];
This is how I save relationships. I am not able to figure out why the relations are being broken once the entity is updated which has no direct link with the entity.
One thing more if I fetch and save the data of any one of the entities like "Inspirations" then all the relations start to work again.
Your code should work. Here are 2 things you need to check:
Make sure related is not nil when you call your method.
Make sure you call save on a valid managed object context.
From your question it seems that entities have 1 to many relationship between them. And by the code you supplied, every things should work fine. Just make sure, you are using the Filter object from the relationship like object.filter (or obj1.obj2.filter), not accessing it via a direct NSPredicate on Filter entity and updating it. And if you are using FRC, you might also need to generate a fault against the parent entities, to get your UI updates.
Looks like I am stuck with decision of planning my Core Data model structure because I am not understand enough clear how Core Data need to work in my case. Now I have an entities Customer and City . Each with few properties in them and without relations between them now. They both have many relationships with other objects, so they are fully independent kind of objects. In my Customer entity I have city property (in what city customer is located). It's value needs to match to value of property name (name of the city)in City entity. Scheme looks like this:
Objects to what City is an alias are formed by parsing JSON file from web and now this part works fine. I added a method in NSManagedObject subclass(generated from entity)for Customer to retrieve the name property value from City entity and store it in city property:
- (City *)city
{
return (City *)[[PTDataFetchHelper sharedInstance] entityForName:#"City" withServerID:self.city_server_id inContext:[self managedObjectContext]];
}
This works without relations, but my UITableView (I am using NSFetchedResultsController like source)start to work horribly slow with this kind of fetching. Also I understand that using this scheme I cannot implement search by both Customer and Cityobjects - I can fetch only from one kind of entity. I found that I can create parent entity for this two, but they are logically and structurally independent. What is the best architectural way to solve this two problems?
Any comments appreciated.
A few observations:
You've made a deliberate effort to avoid setting up a relationship between City and Customer in the model. I'm not sure why based on what I understand about your requirements. You make the comment that you "added a method in NSManagedObject subclass for Customer to retrieve the name property value from City and store it in city property." but that's not what it seems you're doing. You've created a getter method for the city property on Customer that dynamically fetches the city name from the context each time it is called. This may be the cause of the slowness you report.
You can create an NSFetchRequest that traverses relationships. Look into:
KVC collection operators
Predicate format syntax
Customer and City are not actually logically independent because customerInstance.city must always be a name that is a cityInstance.name as you have it structured now.