Using Fetched Results Controller in Coredata One - Many Relationship

Attributes - customerName ->> monthNumber,
amountDeposited
I able to save and retrieve the data but am not able to categorize them into sections using NSFetchedResultsController and show them in a table View.

I have two tables and in one table I want to show customerName in the section and in another one I want to show the monthNumber.

Ok, the lack of code formatting confused me, so you can disregard what I said earlier about the code being wrong.

You are not doing an adequate job of explaining the problem. What is 20? What is 40? Where does it come from? And I asked you for an example of what you are actually seeing right now, but you did not provide that.

Sorry about not being clear.I added transactions to the customer which is a to-many relationship.For instance i have added 6 customers and 3 transactions for each customer. I want the customer name in the header and the transactions in the rows.

With the code I provided.I am getting only one row and only one transaction is being shown.

Notice that line 1 and 3 access the FRC the same way. Then you do it differently for 5. These should all be the same.

In this particular case, it matters which way you do it, and #5 is the only correct one. #5 is the only one that calls your method here:

- (NSFetchedResultsController *)fetchedResultsController { ... }

The first two do not call this method. Since this method must be called in order to create the FRC in the first place, failing to call it means the FRC does not get created. You must be calling it from somewhere else, because in the code you have shown here, I'm surprised you are getting any results at all.

This is the difference between instance variables and properties. And it is a difference that you absolutely must understand. This is not optional.

Lastly, your use of bracket syntax vs dot syntax:

return [_fetchedResultsController sections].count;

This is horrible style. For one thing, be consistent. Dot syntax is only supposed to be used for accessing properties. In this case, you have it exactly backwards. sections is a property, but count is not. So if you must use dot syntax, the correct way to do so would be:

I don't believe you can achieve your goal using only an FRC. An FRC depends on a fetch request, and a fetch request can only fetch a single kind of entity. In this case, the entity that you want is the transaction. You would then be relying on the sort descriptor to adequately sort and section these transactions, but I don't think you can do that with a relationship.

I think the easiest thing to do will be to continue to use the FRC with the customer as you are now, but then you will have to manually sort the transactions. You will also have to map between index paths in the table and index paths in the FRC, because they will not match any more.

Change the FRC so that it is not sectioning the results, simply sorting the customers as you want. This will result in a list of customers in the order that you want, but a single list, not grouped. Then you'll need to adjust how you populate the cell accordingly.

For example:

- (void)configureCell:(UITableViewCell *)cell
atIndexPath:(NSIndexPath *)indexPath
{
// The section in the table view will need to be converted to a row in the FRC
NSIndexPath *adjustedIndexPath = [NSIndexPath indexPathForRow:[indexPath section] inSection:0];
// Now retrieve a person using the adjusted index path
XXPerson *person = [[self fetchedResultsController] objectAtIndexPath:adjustedIndexPath];
// Retrieve and sort the transactions
NSSet *unsortedTransactions = [person transaction];
// By the way, to-many relationships should be named with a plural, to indicate that there will be many objects.
// to-one should be singular.
// So this property name should instead be "transactions".
NSArray *sortedTransactions = [unsortedTransactions sortedArrayUsingDescriptors: ... ];
// I recommend making a property for the descriptor array, since you will be using it a lot
// Now we need to select the appropriate transaction for this row
XXTransaction *transaction = [sortedTransactions objectAtIndex:[indexPath row]];
// Populate the cell with the transaction
cell.textLabel.text = [NSString stringWithFormat:@"%@", transaction];
}

Number of sections will be the number of customers, and number of rows in each section will be the count of transactions for each customer. You will need to adjust the index path as I have shown here in order to provide that value.

So you're still mostly using the FRC, but you're having to do some manual additional work. I believe I have tried to solve a similar problem in the past, but was not able to do so using the FRC alone.

Trying to best understand the exact issue as well. However, what I am getting is that you have two tables with a "to many" relationship. It appears that your first table may be the customer and the second transactions. Of course one customer can have multiple transactions. You want a table that uses the customer's name from the customer table as the section header and then you want to use the appropriate transactions from the relationship to populate the rows. Is this correct?

Assuming the above you are indicating that you are only getting a single row returned (transaction) where you expected 3 to be returned (assume 3 transactions). It appears to me that you are not looking into the relationship to ascertain this though. You are looking at the section header of customer which would show a single row as there is only 1 customer record. You need to look into the NSSet of the customer record that actually contains the relationship (i.e. transactions) you are interested in. The set will contain the correct number of objects related to the customer's transactions (in this case 3).

To take my points above a little deeper. I don't know the name of the attribute in your customer entity that contains the relationship to transactions. So for the purpose of this example I will call it "myTransactions". So your customer entity has an attribute called myTransactions that is itself an NSSet containing the relationship. I will also use Customer as the class name for the customer data.

Your one customer will return one row and so you can directly at that record in row 0 of the appropriate section. Now you use count to determine the number of rows for the section. The code above is contained in the numerberOfRowsInSection method.

You can't store the results in a property. Well, I suppose you could, but it doesn't make sense. These will be different for each person, meaning you will have more than 1 set of transactions, so it doesn't make sense to only hold 1 set of transactions.

As I said, make a property for this. Don't ignore advice. If you don't understand the advice then ask for clarification, but don't ignore it. I didn't type that out just because I felt like typing more. You are going to bounce off of this code for every single row in your table. This code needs to be fast. That means minimizing the amount of work done, and the number of objects created. So make a property for it: