Re: NSArrayController - how?
Re: NSArrayController - how?
- Subject: Re: NSArrayController - how?
- From: William Squires <email@hidden>
- Date: Sat, 09 Jul 2011 20:32:29 -0500
On Jul 8, 2011, at 9:49 PM, Ken Thomases wrote:
> On Jul 8, 2011, at 8:16 PM, William Squires wrote:
>
>> Here's what I have
>>
>> plist file -> NSMutableArray of NSDictionary instances
>
> Don't focus on the array object. Focus on the object which has a to-many relationship property which is implemented via the array.
>
>> NSDictionary instances all have the same keys, but different values (like a database record)
>>
>> each NSDictionary maps to another class, RBSStore
>
> You might consider making the to-many relationship property (and thus the actual array) contain RBSStore objects instead of dictionaries. That is, maybe just use dictionaries on the way in and out of the plist (until the day you decide to move away from a plist as your storage format).
>
Actually this is because the plist itself is a resource in another Xcode project for iOS (i.e., the plist is a template that the iOS app uses (after copying so it'll be read/write) internally for its data store - the app is so simple that fooling around with CoreData is just overkill. Plus, the Foundation classes (NSArray, NSDictionary, etc...) can already work with plists.
I map the RBSStore<->NSDictionary so I won't have to fool around with having the RBSStore class implement NSCoder, and all the hoopla that would involve. (though that's a planned update... sometime in the future.)
>
>> I've got the UI laid out, including the NSTableView (for displaying the NSDictionarys in the NSMutableArray, NSTextFields for each individual column (so that when you select a row, that row's info shows up in the NSTextField's, and one NSSearchField (not implemented yet.)
>
> I assume you mean that the table columns use NSTextFieldCell as their cell type. Right?
>
No, I mean that the window contains NSTextFields and an NSTableView. When a row is selected in the table view, the corresponding values in each column also appear in the NSTextFields so the user (me) can edit them.
The table view (cells) is/are not editable, nor is there any intention of making the cells editable, just like you wouldn't make the cells in a UITableView (root view controller) editable - touching would expand them (push another edit view controller) to another view where the user can edit the info. If the edited info is something that the root view controller loads into the cell, then when the view controller is done, and popped off, then the root view controller will [<container> reloadData] to redisplay, instead. A good example is the Contacts.app on an iPhone/iPod Touch.
In this case (the MacOS X app I'm making), there is no extra view; the info is simply displayed in the NSTextFields (configured as editable text fields, not labels), along with two NSButtons (configures as check boxes), and an NSComboBox (to select time zone the store is in) above the NSTableView.
>
>> Mostly, this is all done via code. How can I transform this into a design that uses bindings and an NSArrayController to eliminate most of the tedious BS, and allow the table view, text fields, and so on to all be linked together so when you update a field, the appropriate row in the table view (and the corresponding NSMutableArray model) all stay in sync?
>
> The cornerstone of bindings is Key-Value Observing which is built on Key-Value Coding. So, the to-many relationship property has to be KVO-compliant for changes to its content. Plus, each item in the relationship has to be KVO-compliant for changes to the properties that you will be binding to.
>
> To make a to-many relationship property KVO-compliant, you should implement the mutating indexed accessors and use those accessors when you need to add, remove, or replace elements of the relationship.
> http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueCoding/Articles/AccessorConventions.html
>
> You can use the -mutableArrayValueForKey: method to get an object that you can treat just like a mutable array but will go through the KVO-compliant methods for you, but that's just a convenience. Generally, it's plenty convenient to simply call your mutating accessors.
>
> After everything is KVO-compliant, you would create an NSArrayController and bind its contentArray binding to the object with the to-many relationship property and to that property. Then, bind each NSTableColumn's value binding to the array controller, with the key path going through "arrangedObjects" and then the property from the dictionary (or RBSStore) that you want that column to show. So, something like @"arrangedObjects.firstName" if the column is to show the firstName property of each element.
>
>
>> Mostly, what I don't understand is: what part of the work does the NSArrayController perform?
>
> You can't do Key-Value Observing _through_ an NSArray or NSMutableArray. NSArrayController and its arrangedObjects property allow for that. It also tracks selection for you. Plus it can do a bunch of other stuff if you want it to, but that should be relatively clear from the API.
>
>> Am I going to need an NSObjectController also to manage the individual rows (which are NSDictionary instances) and their corresponding NSTextFields?
>
> No.
>
>> The big problem is the docs just describe the programmatic interface to the CoreFoundation classes, but not how to use them in real-world situations, or how to use them within IB.
>
> Have you read the Cocoa Bindings Programming Topics?
> http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaBindings/CocoaBindings.html
>
> Also see mmalc's Cocoa Bindings Examples and Hints page:
> http://homepage.mac.com/mmalc/CocoaExamples/controllers.html
>
> Here's another tutorial:
> http://cocoadevcentral.com/articles/000080.php
>
> To the extent that you're setting up bindings in code while these discuss setting things up in Interface Builder, it should be straightforward to just translate from the IB stuff directly to code. IB is just a visual shorthand for the same sort of thing you'd do in code.
>
> Regards,
> Ken
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden