Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Nov 2, 2010, 07:03 PM   #1
BadWolf13
macrumors 6502
 
Join Date: Dec 2009
Core Data Fetch With Sorting

Ok, doing my first Core Data app, and I'm running into one issue. Core Data apparently doesn't always save and fetch in the same order, so every time I start the app, the objects are being displayed in my tableView in a different order. Now I understand the idea of using sort descriptors with a fetch request, but the Array Controller that I'm binding to the tableView and Managed Object Context is apparently fetching automatically, cause there's no code in my program that's doing that. So how do I make it sort, when I'm not controlling the fetch process with code?
BadWolf13 is offline   0 Reply With Quote
Old Nov 3, 2010, 10:42 AM   #2
JoshDC
macrumors regular
 
Join Date: Apr 2009
NSArrayController has setSortDescriptors: and setAutomaticallyRearrangesObjects: (or manually rearrangeObjects). Using these appropriately on the ArrayController you're binding to should do what you want and completely remove the need to sort at fetch time.
JoshDC is offline   0 Reply With Quote
Old Nov 3, 2010, 05:33 PM   #3
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
Thank you, but wouldn't binding the array controller to a sort descriptor interfere with the user's ability to sort the table by clicking on the column headings?
BadWolf13 is offline   0 Reply With Quote
Old Nov 3, 2010, 06:27 PM   #4
JoshDC
macrumors regular
 
Join Date: Apr 2009
I don't have a great example to test it out with, but it works fine when reversing sort order in a single column table. I would try it out and see.
JoshDC is offline   0 Reply With Quote
Old Nov 3, 2010, 07:49 PM   #5
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
This is a multiple column tableView though. The user should be able to sort using any of the columns.
BadWolf13 is offline   0 Reply With Quote
Old Nov 4, 2010, 11:36 AM   #6
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
Ok, it works, but it's highlighting the column of the tableView that it's sorting by. It doesn't look very professional and could be rather distracting to the user. I also don't see why it's doing that, given that the array controller is doing the sorting, not the tableView.

Last edited by BadWolf13; Nov 4, 2010 at 03:34 PM.
BadWolf13 is offline   0 Reply With Quote
Old Nov 4, 2010, 04:02 PM   #7
JoshDC
macrumors regular
 
Join Date: Apr 2009
Untick the column checkbox in the selection section of the table view's attribute inspector, or call setAllowsColumnSelection:NO.

If you're using complex sort descriptors, like manufacturer then part number, you might want to add something like this to your table view's datasource:

Code:
- (void)tableView:(NSTableView *)aTableView 
sortDescriptorsDidChange:(NSArray *)oldDescriptors
{
    NSSortDescriptor *newSortdescriptor = [[aTableView sortDescriptors] objectAtIndex:0];
    
    if ([[newSortdescriptor key] isEqualTo:@"manufacturer"] ) {
        NSSortDescriptor *partDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"partNumber"
                                                                         ascending:YES
                                                                          selector:@selector(caseInsensitiveCompare:)];
           
        
        NSSortDescriptor *manDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"manufacturer"
                                                                        ascending:[newSortdescriptor ascending]
                                                                         selector:@selector(caseInsensitiveCompare:)];
        
        
        
        NSArray *sortDescriptors = [NSArray arrayWithObjects:manDescriptor,partDescriptor, nil];
        
        [arrayController setSortDescriptors:sortDescriptors];
    }
}
JoshDC is offline   0 Reply With Quote
Old Nov 5, 2010, 12:54 AM   #8
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
The column checkbox is already unchecked.

Let me try to explain this better. With the highlight of the column heading, it looks like the sorting is happening in the tableView, but I want it to happen in the array controller or, ideally, within the managed object model. Shouldn't that be a lot simpler?
BadWolf13 is offline   0 Reply With Quote
Old Nov 15, 2010, 09:04 AM   #9
jared_kipe
macrumors 68030
 
jared_kipe's Avatar
 
Join Date: Dec 2003
Location: Seattle
Send a message via AIM to jared_kipe
NSArrayController has a couple of fine looking methonds.

- setSortDescriptors:
- setAutomaticallyRearrangesObjects:
jared_kipe is offline   0 Reply With Quote
Old Nov 15, 2010, 12:49 PM   #10
JoshDC
macrumors regular
 
Join Date: Apr 2009
So you want to be able to select the sort column, but not have that column header become highlighted? While I don't understand your reasoning for this as it changes expected behaviour, I've been able to do this, albeit hackily, by using setHighlightedTableColumn:.

This method seems to only work if it's sent a valid NSTableColumn (so you can't just send nil and have no column header highlighted) so what I've done is create an extra table column, set it to hidden and then set that as highlighted when sort descriptors change (see previous post on the data source method for this).
JoshDC is offline   0 Reply With Quote
Old Nov 15, 2010, 05:00 PM   #11
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
Jared, thank you. Those are exactly the methods I'm using through an IBOutlet linked to my Array Controller. It is sorting properly, but it's having an undesirable side effect.

You know when you click on the a column header to sort by that column, it highlights the column header in blue and gives you a triangle showing the direction of the sort? Well, it's doing that when the window first opens, for the column corresponding to my NSSortDescriptor. Many programs that I use sort the information in their tableView, but don't highlight the column headers until the user selects one to sort manually. That's the effect that I'm looking for. Does it make sense?
BadWolf13 is offline   0 Reply With Quote
Old Nov 16, 2010, 01:11 PM   #12
jared_kipe
macrumors 68030
 
jared_kipe's Avatar
 
Join Date: Dec 2003
Location: Seattle
Send a message via AIM to jared_kipe
Quote:
Originally Posted by BadWolf13 View Post
Jared, thank you. Those are exactly the methods I'm using through an IBOutlet linked to my Array Controller. It is sorting properly, but it's having an undesirable side effect.

You know when you click on the a column header to sort by that column, it highlights the column header in blue and gives you a triangle showing the direction of the sort? Well, it's doing that when the window first opens, for the column corresponding to my NSSortDescriptor. Many programs that I use sort the information in their tableView, but don't highlight the column headers until the user selects one to sort manually. That's the effect that I'm looking for. Does it make sense?
The effect you are looking for makes complete sense. Some information on how your program is wired up is required.

Are you subclassing NSArrayController?
Why use IBOutlets to these methods? Why not call them programmatically when either your NSArrayController is created, or inside your subclasses init methods?

EDIT: Oh and if you post code, I can probably get this working no problem.
jared_kipe is offline   0 Reply With Quote
Old Nov 16, 2010, 05:23 PM   #13
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
1. I'm not subclassing NSArrayController.
2. The use of IBOutlet is how I know of connecting my code to my XIB file, which is where the NSArrayController is.
3. Not much code to post in relation to this particular issue, since most of it's being handled by bindings.

Speaking of bindings, I tried getting rid of these two lines of code and using the Sort Descriptor binding in the XIB file, but that's not doing anything.
BadWolf13 is offline   0 Reply With Quote
Old Nov 16, 2010, 05:51 PM   #14
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
Ok, another question. If I unchecked the Prepares Content box for my array controller in Interface Builder, could I then still get the information into it by writing code similar to;

Code:
[arrayController setContent [moc executeFetchRequest:request error:&error]];
with moc and request being defined earlier? If so, where in my code would I put that? ApplicationDidFinishLaunching, Init?
BadWolf13 is offline   0 Reply With Quote
Old Nov 16, 2010, 10:15 PM   #15
jared_kipe
macrumors 68030
 
jared_kipe's Avatar
 
Join Date: Dec 2003
Location: Seattle
Send a message via AIM to jared_kipe
I personally believe the simplest thing to try would be to subclass NSArrayController and override only initWithCoder to call super's initWithCoder and then setup

- setSortDescriptors:
- setAutomaticallyRearrangesObjects:

As needed.

In InterfaceBuilder just change the class of your already wired up one to be your subclass and all set.

Probably take 5 minutes total.
jared_kipe is offline   0 Reply With Quote
Old Nov 17, 2010, 11:41 AM   #16
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
Ok, couple of questions. First, why would I use initWithCoder instead of just init? Also, I'm currently calling those two methods in my applicationDidFinishLaunching method. Is it really going to make that much of a difference to move them into an init method?
BadWolf13 is offline   0 Reply With Quote
Old Nov 17, 2010, 12:49 PM   #17
JoshDC
macrumors regular
 
Join Date: Apr 2009
initWithCoder: is what gets called in place of init when initialising an object that's be serialised in a .nib. It won't (or at least shouldn't) make a difference if you move the method calls there.

I understand your problem but can't think of a neat solution. For what it's worth I prefer to have the sorted column always highlighted and would find what your describing confusing. Sorry I can't help further.
JoshDC is offline   0 Reply With Quote
Old Nov 17, 2010, 07:54 PM   #18
jared_kipe
macrumors 68030
 
jared_kipe's Avatar
 
Join Date: Dec 2003
Location: Seattle
Send a message via AIM to jared_kipe
Quote:
Originally Posted by BadWolf13 View Post
Ok, couple of questions. First, why would I use initWithCoder instead of just init? Also, I'm currently calling those two methods in my applicationDidFinishLaunching method. Is it really going to make that much of a difference to move them into an init method?
Hold on, so if you DO call those methods it sorts and also highlights.

If you don't then it doesn't sort but also doesn't highlight?
jared_kipe is offline   0 Reply With Quote
Old Nov 17, 2010, 08:58 PM   #19
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
Quote:
Originally Posted by jared_kipe View Post
Hold on, so if you DO call those methods it sorts and also highlights.

If you don't then it doesn't sort but also doesn't highlight?
Exactly.
BadWolf13 is offline   0 Reply With Quote
Old Nov 17, 2010, 11:47 PM   #20
jared_kipe
macrumors 68030
 
jared_kipe's Avatar
 
Join Date: Dec 2003
Location: Seattle
Send a message via AIM to jared_kipe
You are correct then.

You'll want to use a fetch request that has sort descriptors assigned for it. Then assign that array into your NSArrayController. You could take some bindings out and put it into a subclass of NSArrayController's initWithCoder:
Or try to put it in your application delegate.
jared_kipe is offline   0 Reply With Quote
Old Nov 18, 2010, 11:36 AM   #21
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
Thank you. Now here's the million dollar question. The array controller is part of my mainmenu.xib file, so where in my app delegate do I put my fetch request? Init, applicationDidFinishLaunching, or WindowDidLoad?
BadWolf13 is offline   0 Reply With Quote
Old Nov 18, 2010, 11:41 AM   #22
jared_kipe
macrumors 68030
 
jared_kipe's Avatar
 
Join Date: Dec 2003
Location: Seattle
Send a message via AIM to jared_kipe
Probably either of the last two. Just try it out.
jared_kipe is offline   0 Reply With Quote
Old Nov 18, 2010, 05:28 PM   #23
BadWolf13
Thread Starter
macrumors 6502
 
Join Date: Dec 2009
Thanks dude, I put some code into ApplicationDidFinishLaunching, and called the setContent for my NSArrayController IBOutlet, and it works beautifully. No highlight until the user clicks on a heading. Then, when I reopen the app, it's back to the default sorting. Thank you for all your help.
BadWolf13 is offline   0 Reply With Quote
Old Nov 19, 2010, 12:05 PM   #24
jared_kipe
macrumors 68030
 
jared_kipe's Avatar
 
Join Date: Dec 2003
Location: Seattle
Send a message via AIM to jared_kipe
Glad it all worked out.
jared_kipe is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
thread Thread Starter Forum Replies Last Post
core data binding not working Javajax Mac Programming 3 Jul 10, 2011 01:23 PM
Resolved: Struggling with Core Data: Part 2 RonC iPhone/iPad Programming 2 May 27, 2011 01:02 PM
How do I count the number of child entities with a specific value? Mr Skills iPhone/iPad Programming 2 Apr 8, 2011 03:49 PM
Help Needed - Xcode 4 Options: Use Core Data Include Unit Tests Mitch1984 iPhone/iPad Programming 3 Feb 26, 2011 03:42 PM
Regenerating NSFetchedResultsController to dynamically change sort descriptor of UITa bicbac iPhone/iPad Programming 0 Nov 4, 2010 03:55 AM


All times are GMT -5. The time now is 11:22 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC