1

I have a program with tableview/details of core data object. One of the attributes is an image (it only appears in the details). I think it's best to save just the path to the image file, rather than the image itself (it seems to me that core data files with images are much bigger than the images, even if there is little more than that...).

Since it is supposed that the user drags the image to the imagewell, I thought that it would be appropriate to bind the imagewell to the array controller (AC) using "Value path" (AC.selection.image). However, this doesn't do anything (the imagewell accepts the image dragged there, but it keeps there when we change selection).

It seems likely to me that I must implement some "Value Transformer", but not the ones which are available (NSUnarchiveFromData and NSKeyedUnarchiveFromData), because I tried those already...

Am I right in this supposition? And if so, what value transformer would that be? Is it something that I'll have to define? Or is this altogether impossible?

Maybe I should add that I'm still using OSX 10.6, and thus some hypothesis seem to be ruled out...

Thanks

  • In your case *it is* something you'll have to define-- you need a custom value transformer. There really aren't that many standard ones. And speaking of old versions of XCode, newer ones would let you have an NSImage attribute that isn't stuffed into your sqlite store with Binary/Allows External Storage attributes... [See the high-voted answer here](http://stackoverflow.com/questions/16685812/how-to-store-an-image-in-core-data). Unsure about older versions. – stevesliva Apr 27 '15 at 23:51
  • Yes, I know that the file (the image file in this case) can be kept out of the store, but it seems to be only for newer versions (starting with 10.7, it seems...). I also have that option in XCode but it doesn't work. So I'll have to dig on how to define that custom value transformer. –  Apr 28 '15 at 07:48
  • I am also a bit unsure on whether or not this is possible. [Here](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/CocoaBindingsRef/BindingsText/NSImageView.html#//apple_ref/doc/uid/NSImageView-SW1) it says that Binding is read-only (but available since 10.3, so it shouldn't be a version issue). –  Apr 28 '15 at 07:53
  • Ah. If AC.selection.*image* is a (for instance) an NSURL, you'd want to bind to `value` with an `NSURLNSImage` transformer. The NSImage->NSURL direction after a user drag-n-drop would give you an opportunity to save the image... hypothetically. I'm also a little uncertain of the details, or I'd answer instead of comment. – stevesliva Apr 28 '15 at 20:49
  • Yes, you are right in that. The problem is that then I'm saving the image and not the path. I tried that before. I also tried to save it as external, but it doesn't; if you check allows external storage I get an error immediatly. Meanwhile I bought some additional ram to upgrade to OSX Lion (the farther I can go with my MacBook 2006) and then I suppose I can do things in a different way. Thank you anyway :) –  Apr 29 '15 at 08:07

2 Answers2

0

Yes. It is possible.

  1. select the image view
  2. Bind it to your object controller. In that value path field, you have to set the path value as string property
  • I tried that and it doesn't work. (I suppose with string property you mean the model attribute.) Actually that's what I did in first time. I think the problem is, as I say in a comment above, with a link, that binding by value path is read-only. Meanwhile I have it working with a regular open panel, using that binding (the same you suggest) to read the image back from the store. It works fine, but it would be beter if the user could just drag the image into the image view, rather than having to use the open panel... But thanks anyway. –  May 27 '15 at 11:43
0

From my experience, the "value path" and "value URL" bindings only work one-way, as in, you can specify the image view's contents with them, but you can't extract the path/URL from a dragged image. The documentation says that the "binding is read-only", which is more than a little ambiguous, but I believe this is what it refers to.

I ended up just using a text box with a path inside, a "Choose…" button, and the image view as merely a preview. If you really want the "Image Well" functionality, however, I'd recommend something like KSImageView (GitHub gist) that grabs the path out of the NSPasteboard and stores/rebroadcasts it. Here's the main method for that functionality (after inheriting from NSImageView):

- (void)concludeDragOperation:(id <NSDraggingInfo>)sender {
    NSPasteboard *pboard = sender.draggingPasteboard;
    NSString *plist = [pboard stringForType:NSFilenamesPboardType];

    if (!plist) return;

    NSArray<NSString*> *files =
        [NSPropertyListSerialization propertyListWithData:[plist dataUsingEncoding:NSUTF8StringEncoding]
                                                  options:NSPropertyListImmutable
                                                   format:NULL
                                                    error:NULL];
    if (files.count == 0) return;

    NSDictionary *userInfo = @{@"imagePath": files[0]};

    [[NSNotificationCenter defaultCenter] postNotificationName:@"KSImageDroppedNotification"
                                                        object:self
                                                      userInfo:userInfo];
}
ThatsJustCheesy
  • 1,091
  • 13
  • 22