Data binding is deprecated?

Discussion in 'Mac Programming' started by CocoaBean, Sep 8, 2009.

  1. CocoaBean macrumors newbie

    Feb 23, 2009

    After finishing the example from Hillegass' book chapter 11 (core data), I debug the app and get the following warning: The "data" binding is deprecated in Mac OS X versions 10.6 and later.

    This is related to binding the imageWell under the data binding. If the data binding is indeed deprecated then what do I use?

    Had a search and can't find what I'm after.

  2. kainjow Moderator emeritus


    Jun 15, 2000
    Bind to "value" instead, which is an NSImage.
  3. CocoaBean thread starter macrumors newbie

    Feb 23, 2009
    Ok, I will do.
    Although Hillegass has a note which says not to bind to the value but the data binding. Will the value bind work differently?
  4. kainjow Moderator emeritus


    Jun 15, 2000
    Not sure what you mean. You bind to data an NSData object, and you bind to value an NSImage. Since NSImageViews display images and not data objects, it really should be an image, which is probably why Apple deprecated the data binding since it doesn't make sense.
  5. CocoaBean thread starter macrumors newbie

    Feb 23, 2009
  6. lordandrei macrumors newbie


    May 28, 2004
    I too came across this problem. However, when I switched the Binding from Data to Value for my NSView, the interface no longer honoured the "Selection." Now whichever image I drag to the interface becomes the image for all selections in the array.

    If I bind to Data, things work correctly, but I get the deprecation warning.

  7. zbrimhall macrumors newbie

    Nov 6, 2009
    Binding to 'value' instead of 'data'

    The problem is of course that your managed object's photo is returned as an instance of NSData, while the 'value' binding on NSImageView expects an instance of NSImage. In order to avoid the deprecation warning and bind to 'value' you need to have a middleman in there somewhere, handling the conversion between NSData and NSImage.

    Enter value transformers.

    In other words, there is no codeless way to bind to 'value'. My solution took three steps:

    1. Create a new class called DataImageTransformer, following the examples in the above-linked Value Transformer Programming Guide. Specifically, for the 'transformedValue:' implementation, I check to make sure that the input is a kind of NSData instance, and then use it to initialize an NSImage instance, which I return. For the 'reverseTransformedValue:' implementation, I check to make sure that the input is a kind of NSImage, then use the 'TIFFRepresentation' instance method to generate an NSData instance, which I return. There are ways to get other kinds of representations (JPG, PNG, etc.), but those are more involved.
    2. Create a new class called AppDelegate, instantiate it in Interface Builder, and set the new instance as the Application's delegate. In AppDelegate.m, implement the 'initialize' class method according to the instructions in the section "Registering a Value Transformer" of the above-linked guide. It'll look something like the following:
      #import "DataImageTransformer.h"
      + (void)initialize {
          DataImageTransformer *dit = [[[DataImageTransformer alloc] init] autorelease];
          [NSValueTransformer setValueTransformer:dit forName:@"DataToImageTransformer"];
    3. In InterfaceBuilder, select the NSImageView, bring up the Bindings inspector palette, disable the 'data' binding (if enabled) and instead bind the 'value' binding, just like the book says to do for the 'data' binding. The one difference is that you're also going to fill in the "Value Transformer" field with the name that you registered the DataImageTransformer instance under in the 'initialize' method (in my example it would be "DataToImageTransformer").

    That should be it. Build and run and see if it works.
  8. Blakadher macrumors newbie

    Sep 10, 2009
    How do you check that an object is a kind of NSData or NSImage?

    Thank you, zbrimhall. This was a very helpful and informative post. I'm a complete noob to XCode and Cocoa development although I am a longtime .Net C# coder. I read through all the information on the value transformers that you linked to and that, along with your help, enabled me to create and implement a value transformer for the NSImageView. The only portion I wasn't able to implement was a check to ensure that the value objects passed to the transformedValue: and reverseTransformedValue: methods are of the appropriate types.

    I ended up just not implementing that check, but I know that is not good coding practice so I've been searching for how to check that the value object passed to those 2 methods is of the correct type. My Google-fu is failing me and I've not found the proper way to do that. Can anyone give me a pointer? Thanks.
  9. zbrimhall macrumors newbie

    Nov 6, 2009
    Look no further than NSObject. There are methods for checking the type of object you're working with, but there're also methods for seeing if objects conform to given protocol, respond to a given selector, etc. Super handy. NSObject is the root of the class hierarchy, so those methods should be available everywhere.
  10. lucasgladding macrumors 6502

    Feb 16, 2007
    Waterloo, Ontario
    The NSObject method isKindOfClass: should be what you need.

    [value isKindOfClass:[NSImage class]];
    [value isKindOfClass:[NSData class]];
    Side note: when starting with bindings, this site has some excellent examples:

    Kind regards

  11. Blakadher macrumors newbie

    Sep 10, 2009
    Hey, thanks to both of you. The help is much appreciated!
  12. mrial macrumors regular

    Jun 13, 2007
    Saint Paul, MN
    Just going thu the book now. Thanks, this works great (after debugging the typos of course:)
  13. mgerst macrumors newbie

    Jan 5, 2011
    Value binding and change attribute of photo to Transformable appears to work

Share This Page