title: Storing NSImage and NSData in a Cocoa Core Data App
body: <p>I am writing a Cocoa App to display a 2-d floating array.  I now want to assign these images to an entity attribute in Core Data, so I use the transformable data type.  </p>
  
  <p>The problem starts when I try to store an NSImage (and / or NSData) within an Entity ("TheEntity") using a transformable attribute, call it "entityImage."</p>
  
  <h2>Here is the error I get:</h2>
  
  <pre><code>CoreData: error: Serious application error.  Exception was caught during Core
  Data change processing.  This is usually a bug within an observer of 
  NSManagedObjectContextObjectsDidChangeNotification.  Cannot create BOOL from 
  object 
  &lt;4d4d002a 00003d12 7f7f7e7c 7a777470 6c67615b 554e473f 372f271e 160d04fc
  f3eae2d9 d1c9c1b9 b2aba59f 9994908c 89868482 81818182 8486898c 9094999f
  a5abb2b9 c1c9d1d9 e2eaf3fc 040d161e 272f373f 474e555b 61676c70 74777a7c 
  ...
  </code></pre>
  
  <p>and so on (pages and pages) which appear to be hexadecimal values for the NSData representing the image.</p>
  
  <p>Below are code listings with comments:</p>
  
  <pre><code>/*First create the greyscaleImage within the App (before storing to Core
    Data). The image size is Nx by Ny:  */
  
  NSImage *greyscaleImage = [[NSImage alloc] initWithSize:NSMakeSize(Nx,Ny)]; 
  
  /*The dataBitMapRep is constructed earlier (not shown) from a float array
  using NSBitmapImageRep.  The greyscaleImage displays fine in an NSImage View,
  I have been writing these to CALayers, so I won't go into those details here. */
  
  /* "greyscaleImage" defined below can display fine within an NSImageView: */
  [greyscaleImage addRepresentation:dataBitMapRep]; 
  
  /* Create an instance of the Core-Data entity "TheEntity":  */
  TheEntity *anEntityInstance = [NSEntityDescription insertNewObjectForEntityForName:@"TheEntity" inManagedObjectContext:moc];
  
  /* Attempt to set value of entity "transformable" attribute (the line below causes the error): */
  [anEntityInstance setEntityImage:greyscaleImage];
  
  /* Have also tried using the bitmap rep directly (doesn't work): */
  [anEntityInstance setEntityImage:dataBitMapRep];
  
  /* Also tried the reverse by setting the tranformable value as NSData (rather than NSImage) and then switched my ValueTranformer output class accordingly as well as the value transformer and reverse transformer code (see the ImageTransformer Value-Transformer code below): */
   NSData *imgData = [greyscaleImage TIFFRepresentation];  
   // Store as NSData in Core Data:
   [anEntityInstance setEntityImage:imgData]; //still gives an error
  </code></pre>
  
  <p>When I take the inverse approach described directly above (after adjusting the ValueTransformer by switching its return type to NSImage Class, see code below), I get a different flavor of the error (one of these listings for each image, only one is listed):</p>
  
  <pre><code>CoreData: error: Serious application error.  
  Exception was caught during Core Data change processing.  
  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  
  Cannot create BOOL from object &lt;NSImage 0x102271f10 Size={125, 125} 
   Reps=("NSBitmapImageRep 0x102272fa0 Size={125, 125} 
  ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) 
  Pixels=125x125 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil
  (faulting) CGImageSource=0x102272070")Cannot create BOOL from object 
  </code></pre>
  
  <p>The Value Transformer is basic. I also set NSLogs everywhere to help troubleshoot (these are not shown):</p>
  
  <pre><code>#import "ImageTransformer.h"
  @implementation ImageTransformer
  + (BOOL)allowsReverseTransformation {return YES;}
  + (Class)transformedValueClass {
      // Have switched back and forth here to try and diagnose bug:
      return [NSData class]; // also tried: return [NSImage class];
  }
  - (id)transformedValue:(id)value {    
      // If returning NSData class then transformedValue is NSData:
      NSData *data = [value TIFFRepresentation]; 
      return data;
      // If returning NSImage class then transformedValue is NSImage:
      // NSImage *imageRep = [[NSImage alloc] initWithData:value];
      // return imageRep;
  }
  - (id)reverseTransformedValue:(id)value {
      // If returning NSData class, reverseTransformedValue is NSImage:
      NSImage *imageRep = [[NSImage alloc] initWithData:value];
      return imageRep;
      // If returning NSNSImage class, reverseTransformedValue is NSData:
      // NSData *data = [value TIFFRepresentation]; 
      // return data;
  }
  @end
  </code></pre>
  
  <p>Thanks for any help or suggestions on why this problem occurs.  I have Googled and checked lots of other Stack articles, have not found anything like this.</p>