5

I have an object called Delivery that has a set of Customer objects associated with it. Each Delivery object also stores a mainCustomerId which is an NSNumber*. I have an NSFetchedResultsController that is used to manage the datasource for a UITableView. The issue is that I want to sort the NSFetchedResultsController by the Customer's lastName field (the customer again is stored in a many-to-many relationship called customers on the Delivery object) where one of the customers in the set has a customerId equal to the Delivery's MainCustomerId.

The Delivery Class Looks like this (only the relevant parts)

@interface Delivery : NSManagedObject
@property (nonatomic, retain) NSNumber * mainCustomerId;
@property (nonatomic, retain) NSSet *customers;
@end

The Customer Class Looks like this

@interface Customer : NSManagedObject
@property (nonatomic, retain) NSNumber * customerId;
@property (nonatomic, retain) NSString * lastName;
// And the inverse relationship to the deliveries
@property (nonatomic, retain) NSSet *deliveries;
@end

I need to make an NSSortDescriptor that does something like this (Note, I know this is the wrong format and will not work. I hope it communicates the idea though)

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"customers.AnyobjectInSet.lastName WHERE AnyobjectInSet.customerId == masterCustomerId ascending:YES];

I have tried several things using subqueries and NSExpressions but always come up short since I can't use any features that use Cocoa (like sorting with @selector) because it has to be able to generate a real mysql query with no Cocoa processing of the data. But I feel like there has to be someway to do this since it would be an easy query in mysql.

select * from Delivery JOIN Customer ON Customer.customerId=Delivery.mainCustomerId ORDER BY Customer.lastName;

I am trying to avoid having to sort after the results are fetched and store the sort order back on the object (which would be easy, but I feel it is the wrong solution since I am selecting the relevant data. There has to be a way to sort by it). Any help would be super appreciated.

Thanks in advance.

johnrechd
  • 1,801
  • 19
  • 25
  • why don't you make use of predicate and then apply sort descriptor. – Leena Mar 02 '13 at 05:56
  • Thanks Leena, I'm not quite sure how I would use a predicate to solve this. I'm not filtering my results by anything. I just need to order them by customer object with the corresponding Id. Do you have an example of what you mean? – johnrechd Mar 04 '13 at 18:04
  • Refer this doc :-http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Predicates/predicates.html – Leena Mar 05 '13 at 04:59
  • Could this be related? It may you with this many-to-many models. http://stackoverflow.com/questions/2328585/core-data-many-to-many-relationship-predicate-question – nhisyam Mar 06 '13 at 07:23
  • Thanks for the link, not quite what I am doing though. The relationship is the same, but I am not trying to find or filter by anything. I simply want to sort by a field that is part of an object in the Customers NSSet. Thanks for taking a look at it. – johnrechd Mar 06 '13 at 20:22
  • 1
    Why don't you replace the mainCustomerId by a (to-one) relationship mainCustomer (from Delivery to Customer)? That would be more in the spirit of Core Data (I think) and makes the sort descriptor trivial. – Martin R Mar 26 '13 at 13:33
  • That's true (which is the way I am doing it now). However, I then have two inverse relationships on customer and would have to look through both anytime I want to see all the deliveries that a customer belongs to. Or, I store the customer in both places and ignore the inverse on the mainCustomer (Also, what I am doing now), but then have a redundant reference. I guess it would just be nice if there was a way to sort this way, although I have the app working currently. Thanks for taking a look and the good suggestion. – johnrechd Mar 27 '13 at 00:44

1 Answers1

2

Ok so maybe I'm missing something but the predicate suggestion makes perfect sense to me. Please correct me if I'm wrong but (assuming you know mainCustomerID):

NSNumber *mainCustomerID = ...

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"customerID == %@", mainCustomerID];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"lastName" ascending:YES];

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Customer"];
[request setPredicate:predicate];
[request setSortDescriptors:@[ sortDescriptor ]];

NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request ...

So basically if its not clear, this will fetch all Customer records where customerID is equal to mainCustomerID and then sort those results by lastName. This WILL internally generate the SQL statement to perform this for you.

Is this not what you're trying to do?

Also if you want to see the SQL that is generated by CoreData at runtime (useful debugging tool), open your scheme and go to the 'Arguments' tab and add the following to 'Arguments passed at launch':

-com.apple.CoreData.SQLDebug 1

Happy Coding :)

Shaps
  • 91
  • 8
  • Thanks Shapps, not quite what I am doing though. I am displaying Delivery objects in my cells and want to sort by a customer in an NSSet that has the same ID as as the referenced master customer. Where the set of customers belongs to the Delivery entity. Basically, I need to sort on a particular object in an NSSet belonging to the fetched entity. Happy coding to you also. – johnrechd Apr 24 '13 at 16:14