Core Data Relationships and saving/fetching - ios

I'm a little confused about the core data mechanisms with respect to object relationships.
I have an "Account" model, and a "Credit Card" model, and I have two questions:
How do I set up a one-to-many relationship from Account to Credit Card and a one-to-one relationship from Credit Card to Account? I'm having trouble figuring out exactly how to set that from the data model in XCode.
If my Account model has a Credit Card property (or an NSSet, it looks like), and I set that property and save the account object, should the Credit Card object associated with it be saved as well? Or does that need to be saved separately? What's the proper way to do this? Conversely, what's the proper way to fetch objects in such a relationship, and to modify and replace them in the core data store, rather than simply inserting?
I know these are pretty basic core data questions, so thank you in advance for your patience.

You need to read this guide. Probably you should change the display style in Xcode to be table based rather than the diagram style.
You don't save individual objects, you save the store as a whole. So all changes are saved at the same time.
When you have an object with a relationship it is presented to you as a set (NSSet as you say). You can iterate that set to find and modify the destination objects, you can also filter the set to find specific objects. You can also run fetch requests with predicates to find the objects you want to modify. There are many options.

Related

How to avoid duplicated records in core data - ios

I'm new in iOS, Swift. My application has one entity named "Category" in a relationship to many entities named "Movies".
"Movies" entities are changing, according to data that I get from a url. I'm looking for a way not to have duplicated movies records in each category, and I can't think of an easy way to do it.
Core-data does not have a built in way to ensure uniqueness. You have to manage that yourself. But it is not that hard. Before every insert/update do a fetch - if it does not exist then create it, it if already exists then update it. If you are updating many at a time (for example from a network request that has updates for many entities) then fetch all of then in a single fetch request and then create or update as needed.
Generally these fetches are done using uniqueIds for each entity. If you don't have any uniqueId for you entities then you have a deeper problem than core data. You could have two movies with the same name, or one movie that has different names. If you don't have anything that says the same, then you fundamentally don't have any way to know if you need to make another entity or update an existing one. It is possible that you can use the movie name, but I would not recommend that. I suggest that you look closer at your server api and see if there is a uniqueId that is served, and if there is none then you have to have it fixed by the server team.

Save data in two persistent stores

I am having an app where there is a search feature that does a network request. However uses the same model framework as the entire app.
This means that when the user searches for something I need to create managed objects from the found data, save them and display them. However this messes up old records with the user recent data.
I would ideally like to save the managed objects found in the search in a separate in-memory persistent store so it doesn't make disorder in the main data.
I haven't done something like this before so what is the best way to approach it?
Thank you!
As has been suggested by #stevesliva, you do not need to involve yourself into the complexities of maintaining multiple partially in-memory stores. The way to go here is to create a child context and fetch the online data into this context. Once you do not need the data any more, just discard the context.
If you decide to save the downloaded data, you can simply "push" the changes to the main context via save:. At that point you could make necessary adjustments to the data so they fit into the user data. Depending on your model, one feasible solution could be to create another attribute on one of the entities that marks linked objects as distinct from the user created objects.

What is best practice to handle Core Data relationship if I don't have the full data-set?

I have two type of models in the application I'm working on: User and Account.
Every account has many users. Every user has one account.
When I download the user object from an API, I get the account_id, but not the actual account object. The account object will be downloaded after the user object.
What is the best practice for establishing the relationship between the user and his account in this situation?
Should I insert an empty row into the Accounts table with just its account_id field filled in? And then later, when I download the account, update that row?
First, Core Data centric definitions, you have 2 entities (User and Account) and no tables (because this is an object store, not a SQLite database).
So, you wouldn't have empty rows, you would have stub objects (partially complete objects that will be filled in later).
There is no best practice when it comes to stub objects. Whether you should create them is entirely dependent upon your use case. In some cases it helps to have the basic information about an item so that you have something to show the user while you go and get the details. In your case, you only have an identity so the benefit of stub objects seems very low.

Core Data: Relationships and User Objects

I'm using StackMob with CoreData (remote Database), but I think this is a general Core Data question.
I have 3 entities:
User (login)
Cars
Bikes
Each entity has several attributes.
A User can have multiple Cars and Bikes objects (to-many relationship). Cars and Bikes can only have one owner (User) (inverse to-one relationship).
Now lets say we have 2,000 Users. Each User is a car dealer and has 500 cars and 300 bikes records/objects stored in CoreData. I would like the User to fetch based on attributes of Cars and Bikes. I plan to use predicates for this. To cut back on constant fetch request, I also plan to use Cache.
However, the questions I have are:
How should I save the record/object under each User? Is there a term for that in CoreData?
I would like the User to login and be able fetch all the Cars/Bikes based on its attributes (Model, Manufacture, DateStamp, etc.) only within the objects the User created. I guess what I'm trying to avoid is when the User does a fetch request based on attributes in the Cars and Bikes entity, it only searches under its own User objects. I don't want the fetch request to search through all the others User's objects because that would be a waste as I'm afraid that'll slow down the app. What's the best way to set this up in CoreData?
Just went though 2 core data books and I'm not sure how to approach this. I know I'm not the brightest so I turn to the experts for some advice. Thank you.
CoreData is actually really excelently optimized. What you need is an NSSearchPredicate and and NSFetchedResultsController. These are both kind of complicated and I can't just "tell" you how to use them. I found this open course to be EXTREMELY helpful
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/
It builds a website fetching app in iOS using core data. Check the Core Data episode and if you don't know what he's talking about go back and watch some earlier ones

storing number of yet nonexistent objects in relationship in Core Data

I have some data that needs to be loaded from the server (backend). For example, let's just say I have an entities of user and event. The relationship between them is many-to-many (user can attend many events and event can have many attendees). All the data is stored remotely on backend and locally in Core Data. When I download data from backend I convert it into NSManagedObjects and store it in NSManagedObjectContext. Everything's very simple, but...
When I download a list of events I want to know, how many attendees this event has. But I cannot download a list of users in the same request, because it's totally overkill. What I need is to download, let's say, a list of users' unique ids so that I can have two things: total number of attendees and means to download detailed data of concrete users (via unique id). Or there's another example: I need to know total number of attendees and download a limited set of them, so I can create some entities in CoreData, but not all of them.
So the main question is how am I supposed to store such information in my CoreData? Meaning I need to know that for some entity there are some related entities in relationship that are not actually currently present in CoreData, but I know how many of them there should be. The first thing that came in my mind is to have a attribute called something like usersCount in my event entity, but that seems to be kind of dirty. What is the best practice for such situation?
Please comment if the question is not clear enough so I can maybe add some more specifics.
When you download an event with a list of corresponding user ids, then you can create
the Event object and also the related User objects, but you fill only the "userId"
attribute in the user object.
Later, when you download the complete user info, you update the existing (incomplete) objects
or create new user objects. Implementing Find-or-Create Efficiently in the "Core Data Programming Guide"
describes a pattern that might be useful.
So the idea is to create Core Data objects with incomplete information first and update the
objects with detailed information later. The advantage is that you can set up all relationships immediatly, and e.g. counting related users works even if the user information
is yet incomplete.
There is nothing dirty about having an attribute to store the count, especially if those entities are retrieved and paged via separate requests.

Resources