Core Data entity design for master-detail interface - ios

I am developing an app with a master-detail interface which displays a list of products that the user can drill down into. On initialisation, the app loads summary information for (1000+) products from a web service and displays it in a table view. When the user selects a particular product, the app calls the web service to get detailed info for that product and displays it in a detail view.
I want to persist this data between sessions using the Core Data framework.
I can think of two approaches for modelling this data.
Use a single Core Data entity Product containing all attributes for this object. When the table view is initialised these entities are populated with summary data. When a particular product is selected, the remaining fields are populated for that product only.
Use two Core Data entities, ProductSummary and ProductDetail with a summary/detail relationship between them. ProductSummary contains the attributes that are loaded by the table view. ProductDetail contains the attributes loaded by the detail view.
What are the pros and cons of each option? Option 1 certainly looks easier to code, but am I storing up memory usage problems for later? Would performance be equivalent?

With as many objects as you are going to have, go with option 2. Keep the data coming in and the attributes of the entity down to only what you need to display in the TV. Set up the relationship to detail and load that when the detail VC comes in.
I am doing something similar except with ~4500 rows. I only store what I need and then turn to the other entity for detail relating to the object.

Related

Core Data Fetched Properties

Though I have been using Core Data for a while now and in a number of apps, I have never yet used Fetched Properties.
In my current project I have an entity with relationships in the Default store, this same entity is also in the Second store.
But in the Second store I want to have some of the relationships changed to Fetched Properties.
Is that possible?
You can replace relationships with fetched properties, but it won't be the same entity anymore. Migrating to a new model using fetched properties is possible, but unless you're using different models for different store files you'll need to make the change in both places. If you want the same model for both, you might consider adding a fetched property while keeping the relationship in place.

Does entity relation also get loaded into memory when entity gets fetched in CoreData?

I'm working on an app that allows the user to create a little comic from a photo. I've implemented CoreData so the user can save and reedit their comic. I've created two entities: ComicInfo and ComicDetails which have a relationship with one another (I did it this way from reading the Ray Wenderlich tutorial). So when the user saves a comic, I make a new ComicInfo NSManagedObject, store the name and thumbnail in it, then I create a ComicDetails NSManagedObject, store various attributes in that, and I store the ComicDetails in the ComicInfo and save.
I've created a UITableView that displays the thumbnails and names from all the ComicInfo objects to allow the user to select one so they can edit the comic.
What I'm wondering is, why did I separate this into two entities instead of just doing them in one? I'm assuming that when I load all of the ComicInfos from CoreData, that the ComicDetails will also be loaded into memory, or am I wrong about that? In a perfect world, I'd like it so only the ComicInfos are loaded when the UITableView is launched, then when the user selects one of the rows, the associated ComicDetails will then be loaded into memory. Is that not what's happening here?
The reason to have two entities is to get the behavior you're hoping for. In general when you do a Core Data fetch, only instances of the entity type you request are loaded into memory. Related objects are not immediately loaded. Instead, Core Data loads them automatically on demand.
In your case, if you fetch ComicInfos, only ComicInfos get loaded. But if you take one of those objects and access its details attribute, the related ComicDetails instance is automatically loaded, without needing to do another fetch. The related objects are only loaded when you ask for them. So, you're getting the behavior you want.
If you ever want to override this behavior, you can use setRelationshipKeyPathsForPrefetching: to force NSFetchRequest to load not only the objects you actually fetch, but also specific related objects as well.

iOS program structuring - SQLite and View Controllers

I'm looking to get some insight on a project of mine before I get too deep into it with possibly a poor setup. The app is a simple database collection with a few table views.
Quick example:
First table view is populated with teacher names. Select the teacher and the next table view is populated with all of the students in that class. Further, select that student and an info view arises with details for that student.
The plan is to use SQLite, so I'm looking to make sure I set views up properly to make it easier on myself later.
My thoughts so far:
TeacherViewController - Grab info from DB to populate the table view. Contains segue within didSelectRowAtIndexPath to jump to StudentView.
StudentViewController - Again grabs info from the DB from that teacher's table to populate with students, with a segue to jump to info page.
StudentInfoView - Contains the forms ready to be populated with info.
There needs to be the ability to add teachers, as well as add students within each teacher/class. Since I haven't dove into SQLite yet, I'd like advice from those experienced.
Thanks, and let me answer any questions you may have.
The most important thing I have found when using SQLite is to ensure that you arrange your views in line with large data captures.
For instance I have a word game and the most intense call to the DB is to generate the starting position of the game. So I do this in a separate thread whilst playing a tutorial, when the viewController first loads. The rest of the calls are quick and easy so can be done at the required time within the game without any impact on performance (i.e. this includes lines like select count(*) from six where word = '%#' - where the DB table has 22000 words)
You will find that sqlite calls are very quick. I think your approach sounds fine as the large calls will be done on the load of the viewControllers where you can easily add loading indicators.
One thing to bare in mind - which can get an app rejected is where you store the sqlite db - because if it is to large then you need to ensure that it isn't backed up via iCloud without asking the user for permission.

How to user Core Data to construct my model object

i am using Core Data for the first time in my iOS application. I am testing how it works, but i have some problems like this : I have 3 entities (Page, User, Note), my application is a book, a user can consult the pages and take notes, the user can take several notes in several pages. How i can organize the model of my objects in core Data and the relationships between my Objects. thanks.
For starters, you might add a Book entity which has to-many relationships with Page and Note. You could also add methods to Book like -pageForPageNumber: and -notesForPage: just to make it easy to access the things you're likely to need. If your app represents a single book, then you can have some appropriate class like your app delegate or your root view controller fetch the one instance of Book in the store. If your app is more like a reader that contains multiple books, you might instead start by fetching all the books and displaying them in a list so that the user can choose one.

Document User Interface using QuantumGrid (TcxGrid) from Developer Express

I need to generate a user interface for entering a sales document (eg invoice). I'm trying to use components of "developer express" specifically the QuantumGrid component (TcxGrid). I've seen the demos of master-detail components and search in the devexpress support center, but none has helped me because all use 2 grids to handle the master-detail relation, and edit multiple records at once.
I just need to edit a record (document) at a time and using a pair of objects dataware components (eg TDBEdit) in the header and a grid to handle the detail.
something like this
Where can I find a basic example of using these components in this way?
Tthe Master/Child properties in the QuantumGrid are mainly designed to nest multiple items in the grid. If you setup the relationship in the data components you can simply hook the controls up to the correct DataSource and everything will work.
So if you have two DataSets Customer and Invoice. The Invoice Master Datasource is the Customer DataSource. Then on your edit controls you point to the Customer DataSource and you point the Grid to the Invoice DataSource.
If you think about what the Master/Detail relationship is doing it really just filters the records on the Detail DataSet to match the current record on the Master DataSet. Individual Edit controls will always display the "current" record in the DataSet they are connected to. Grids will show all visible records in the DataSet they are connected to.
I have a tendency to not use Master/Detail relationships in an edit form like you show here. I'm assuming there is some way on a different screen to pick the invoice to edit. I usually create a copy of the needed DataSets with only the records needed for this edit. If I am editing a existing invoice I copy the current records. If it is a new invoice I can start off with an empty recordset. It is more work - I have some generic library functions that will copy a DataSet Structure and then copy one or more records into that Dataset. Depending on your setup you can also requery your Database to just get the records you are interested in. Obviously that should not be done in all cases. Another issue with this approach is you need a way to update any other Datasets you may have with this data - i.e. your main search screen.
However, once I get on the edit screen I find it makes things eaiser. Now I don't need to worry about the master detail relationship at the top level. If the invoice has internal Master/Detail relationships you can just deal with those, but you know that the DataSets only have the data for this one invoice - not everything in the Database.
In the case of your form if you limit the Data in the DataSets you can just hook everything up directly and it should work as you expect. You would only have one record in the Customer DataSet and the invoice would just have the records for this Invoice.
I think you'll need to take care of the master-detail relations in your ClientDataSource components. The grid will then follow this relation.
Why don't you ask this at support#devexpress.com ?
The reason why I have a vcl subscription is, apart from the quality of the components of course, because they do have a great support site and staff ?
There you ask it directly to the people who have written the stuff, and they are most likely happy to supply you with a sample program (at least I have received a lot of samples over the years).
The premise is the same as with any other master-detail relationship, regardless of the components. You will need to setup the master-detail on the dataset level to accomplish what you want.

Resources