I am having issues creating, and understanding how to create a core data model for this situation.
(1) A person can have multiple pets (either combination of a Dog or Cat).
(2) There can be multiple people too.
I want to go through the Person entity and pull each person, and each pet and there information.
I'm not sure if I should use a relationship, or how can I set this model up in Core Data. I quickly jotted down a picker of what I thought the model would look. I made this model for simplicity sake, my model doesn't deal with Cats and Dogs.
Any suggestions or ideas is greatly appreciated.
Inverse relationships enable Core Data to propagate change in both directions when an instance of either the source or destination type changes. Every relationship must have an inverse. When creating relationships in the Graph editor, you add inverse relationships between entities in a single step.
Core Data is a framework that you use to manage the model layer objects in your application. It provides generalized and automated solutions to common tasks associated with object life cycle and object graph management, including persistence.
The next time you need to store data, you should have a better idea of your options. Core Data is unnecessary for random pieces of unrelated data, but it's a perfect fit for a large, relational data set. The defaults system is ideal for small, random pieces of unrelated data, such as settings or the user's preferences.
Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.
I quickly put together a model for you:
So, basically "Person" is your person, which has a relationship "pets" - this is a "to many" relationship. One person can have multiple pets.
Then there is a "Pet" entity. It's an abstract entity that represents any pet, cats and dogs alike. It has an inverse relationship to "pets" of "Person". Therefore, from any pet, you can always trace back to the corresponding owner. Also, every subclass of "Pet" will have some common attributes, like age/name/weight.
Additionally, subclasses (entities which have "Pet" as "Parent Entity", like "Dog" and "Cat") can have their own attributes in addition to the attributes of "Pet", like a "Dog" has a "barkSound", and a "Cat" has a "meowSound".
You can of course add as many persons into your storage as you want, this has nothing to do with the data model.
To retrieve the information, simply use a fetch request to fetch all persons. Then loop through them and access their "pets" property to get NSSets for their pets. You can loop through those sets to access the information of the pets.
Here is an example of how to fetch all persons, then all pets:
// Fetch all persons
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:yourContext];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *fetchedObjects = [yourContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle error case
}
[fetchRequest release];
// Loop through all their pets
for (Person* person in fetchedObjects)
{
NSLog(@"Hello, my name is %@", person.name);
for (Pet* pet in person.pets) {
if ([pet isKindOfClass:[Dog class]])
{
NSLog(@"Woof, I'm %@, owned by %@", pet.name, pet.owner.name);
}
else
{
NSLog(@"Meow, I'm %@, owned by %@", pet.name, pet.owner.name);
}
}
}
Note that you can also just fetch the pets, without going through their owners:
// Fetch all persons
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Pet" inManagedObjectContext:yourContext];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesSubentities:YES]; // State that you want Cats and Dogs, not just Pets.
NSError *error = nil;
NSArray *fetchedObjects = [yourContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle error case
}
[fetchRequest release];
The code above is not tested, and might include typos, but will give you the idea on how to do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With