Re: Dragging NSManagedObject subclass within app
Re: Dragging NSManagedObject subclass within app
- Subject: Re: Dragging NSManagedObject subclass within app
- From: Kyle Sluder <email@hidden>
- Date: Sun, 10 Mar 2013 21:01:33 -0700
On Sun, Mar 10, 2013, at 08:24 PM, Rick Mann wrote:
>
> On Mar 10, 2013, at 20:16 , Graham Cox <email@hidden> wrote:
>
> > Yes, just store the pointer somewhere that the source and destination can both access it. You don't even need the pasteboard, except perhaps to put a dummy item on it (I often use an empty string) to keep the drag manager happy. Also use the NSDragOperationPrivate operation mask to stop anyone else trying to interpret your drag.
>
> That's just so ugly, though. The pasteboard should just accept keyed
> objects, like NSDictionary, precisely for this purpose, especially if you
> have to put *something* on it.
You don't have to put anything on the pasteboard. If you use the
old-school -dragImage… API, the destination can perform all its
communication with the source without touching the pasteboard if
desired. Obviously you cannot use the new -beginDraggingSession… API to
do this, since that requires an array of NSDraggingItems.
Pasteboards are already keyed by data type (previously pasteboard types,
nowadays UTIs), so I'm not clear on what advantage you would gain from a
"keyed object" interface. If your data doesn't make sense in another
app, just use a private UTI as your type.
>
> I tried everything I could think of to do this "right," including putting
> the NSManagedObject's URL onto the pasteboard, and creating a "Source"
> protocol that the source implements to allow the destination to get at
> the MOC for that URL. But then Core Data makes it egregiously difficult
> to get the NSManagedObject back from the URI.
This is definitely the approach I would have taken. But you don't want
to just use plain-jane URLs here, because then if you drop on another
app they will be able to read it. So I'd create a simple class to wrap a
managed object ID URI that implements NSPasteboardReading and
NSPasteboardWriting:
@implementation ManagedObjectURIPasteboardItem /* : NSObject
<NSPasteboardReading, NSPasteboardWriting> */
{ NSURL *_url; }
- initWithManagedObjectID:(NSManagedObjectID *)moid {
if ((self = [super init]))
_url = [[moid URIRepresentation] copy];
return self;
}
- (void)dealloc {
[_url release];
[super dealloc];
}
- (NSArray *)writableTypesForPasteboard:(NSPasteboard *pb) {
return @[@"com.mycompany.ManagedObjectURIPasteboardItem"];
}
- (NSPasteboardWritingOptions)writingOptionsForType:(NSString *)type
pasteboard:(NSPasteboard *)pb {
return 0;
}
- pasteboardPropertyListForType:(NSString *)type {
return [_url absoluteString];
}
+ (NSArray *)readableTypesForPasteboard:(NSPasteboard *)pb {
return @[@"com.mycompany.ManagedObjectURIPasteboardItem"];
}
+ (NSPasteboardReadingOptions)readingOptionsForType:(NSString *)type
pasteboard:(NSPasteboard *pb) {
return NSPasteboardReadingAsPropertyList;
}
- initWithPasteboardPropertyList:(id)plist ofType:(NSString *)type {
if ((self = [super init]))
_url = [[NSURL alloc] initWithString:(NSString *)plist];
return self;
}
@end
Theoretically, one could do this in a category on NSManagedObject, but
who knows if someone else will have implemented such a category already!
Also, you might want to turn the UTI into a parameter so that you can
reuse this class with managed objects that should not be draggable to
all possible destinations that accept managed objects (for example,
Employees shouldn't be droppable on the Departments table).
When beginning the drag, wrap your MO IDs with instances of this class
and use those to create your NSDraggingItems. Your destination can then
unpack them using -enumerateDraggingItems… and convert them back into
NSManagedObjects via the PSC.
> In the end, I just created an NSData* straight from my object's pointer.
> I'm about to ARC-ify my code (it was GC), so I'll add bridging
> retain/release to that, but really, the pboard should allow me to just
> put retained references onto it.
This also works, but I'd be leery about violating Core Data's
confinement rules now or in the future. MO IDs are the safe way to go.
--Kyle Sluder
_______________________________________________
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