Binding Operators With Core Data

Tim Isted posted an excellent tutorial on building Core Data applications with multiple windows which really cleared up some of the mystery of using Core Data for me. He guides you through the process of modifying a “Core Data Document-based Application” project to support multiple windows per document. There are a few enhancements to the project that simply cry out to be made.

Tim notes that the user interface can be improved by ensuring that the “add” and “remove” buttons for the Departments and People are enabled and disabled based on the state of the model. This is, as he points out, pretty simple, and it’s described in very nearly every bindings tutorial out there. Simply bind “Enabled” to the canAdd and canRemove keys of the appropriate NSArrayControllers.

Properly enabling and disabling the “open employee window” button is slightly more difficult: where the other bindings in this tutorial simply bind values (the departments to display, the name of the person, etc.) here we’re interested in binding to a property of the value — whether it’s empty or not — rather than the value itself. Happily, this is almost as trivial as the previous cases. Rather than simply binding the values of a controller or model we’ll need to use an operator to transform the value of a controller key so that we can use it.

The enabled binding expects its bound value to be a boolean: a widget is either enabled or disabled. The select of an NSArrayController is some other collection or other (I’m not entirely sure which, but it’s definitely not a BOOL). To transform this possibly empty collection of NSManagedObjects into an empty-or-not BOOL we can exploit one of it’s operators @count (the rest are describe in the Set and Array Operators section of the Key-Value Coding Programming Guide). @count is basically just the good old count: method from NSArray: called on a collection, it returns the cardinality of that collection as an int. As we all know, most C-based and C-like languages allow you to treat pretty much anything as a BOOL with 0 being NO and every other value YES. This is exactly what we want.

To solve our problem then, we should bind “Enabled” for the “open employee window” button to “People.selection.@count”. Now the button should be disabled when no people are selected and enabled when there are people are selected.

Button disabled with no selection

Button enabled with selection

Alas, the rest of the set and array operators (@sum, etc.) don’t seem to work. See more on this problem in Computed Attributes in Core Data, How? and one (not entirely pleasing) solution in Emulating Operators for Core Data.

Share and Enjoy:
  • del.icio.us
  • Reddit
  • Digg
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • LinkedIn
  • StumbleUpon
  • Technorati
  • Twitter
This entry was posted in Cocoa and tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Comment

  1. Posted July 18, 2008 at 10:42 am | Permalink

    Thank you for posting on my article.

    One way to get the same functionality would be simply to bind to the People controller’s canRemove key as this is only true if a person (or multiple) is selected. Doing it this way seems like a bad thing to do and, although I can’t think of a reason why it shouldn’t be done this way, I much prefer your version!

    I’ve edited in a link to your post from mine —- I hope this is ok.

2 Trackbacks

  1. […] - Edit - handling enabling and disabling of the ‘Open Employee Window’ button is a little more complicated than the ‘+’ and ‘-’ buttons — there is a great post on how to do exactly this available at: http://www.passingcuriosity.com/. […]

  2. […] than to start from scratch, so I’ll do the same. Continuing from where I left my post on using bindings operators with Core Data we’ll first extend our app to display the number of employees in each […]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">