Reputation: 1768
I'm making an application from which I want to be able to drag an image to into a specific 3rd party application, Anki. The image is loaded from the Internet, and so does not exist on the hard drive. The API documentation seems to offer three methods of doing this (note that I purposely omitted alternatives that use API functions that are now deprecated):
Method #1 - Method #1 works with Anki and some other applications. However, it involves creating a temporary file on the desktop. This is not ideal.
Method #2 - I could not get method #2 to work at all. The code compiles and runs without error, but dragging the image appears to do nothing no matter what application I drop the image on.
Method #3 - Method #3 works with some applications. For instance, I can drag the image into a folder in finder, and it creates the image where I dropped it. However, Anki will not accept files this way.
So, my question is 2-part:
Can method #2 be made to work? This would avoid creating unnecessary temporary files, and so would be ideal. NSImage supports NSPasteboardWriter, so it seems like it should work. But, I can't find an example of how to do it.
If I must use method #1, where is the recommended place to put temporary files like these? If I must create a temporary file in order to drop the image into my target application, then where is the recommended place to put files like these?
//
// DraggableImageView.swift
// Lang Search
//
// Created by Kevin Yancey on 11/21/14.
// Copyright (c) 2014 Kevin Yancey. All rights reserved.
//
import Foundation
import Cocoa
import AppKit
class DraggableImageView : NSImageView, NSDraggingSource {
//Method #1 - It works, but isn't ideal yet...
override func mouseDragged(theEvent: NSEvent) {
if let image = self.image {
let imgRep = image.representations[0] as! NSBitmapImageRep;
let data = imgRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: NSDictionary() as [NSObject : AnyObject])!;
data.writeToFile("/Users/kpyancey/Desktop/copiedImage.png", atomically: false);
let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: NSURL.fileURLWithPath("/Users/kpyancey/Desktop/copiedImage.png")!)
let draggingItems : [AnyObject] = [draggingItem]
let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
}
}
//Method #2 - doesn't seem to work at all
/*override func mouseDragged(theEvent: NSEvent) {
if let image = self.image {
let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: image)
let draggingItems : [AnyObject] = [draggingItem]
let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
}
}*/
//Method #3 - works, but not with the target application (Anki)
/*
override func mouseDragged(theEvent: NSEvent) {
if let image = self.image {
let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: image)
let draggingItems : [AnyObject] = [draggingItem]
let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
}
}*/
/*
override func mouseDragged(theEvent: NSEvent) {
var dragPosition = convertPoint(theEvent.locationInWindow, fromView: nil)
dragPosition.x -= 16
dragPosition.y -= 16
let imageLocation = NSRect(origin: dragPosition, size: NSMakeSize(32, 32))
self.dragPromisedFilesOfTypes(["png"], fromRect: imageLocation, source: self, slideBack: true, event: theEvent)
}
override func namesOfPromisedFilesDroppedAtDestination(dropDestination: NSURL) -> [AnyObject]? {
let imgRep = image!.representations[0] as! NSBitmapImageRep;
let data = imgRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: NSDictionary() as [NSObject : AnyObject])!;
let filePath = dropDestination.URLByAppendingPathComponent("test.png")
data.writeToURL(filePath, atomically: false);
return [filePath]
}*/
func draggingSession(session: NSDraggingSession, sourceOperationMaskForDraggingContext context: NSDraggingContext) -> NSDragOperation {
return NSDragOperation.Copy
}
}
Upvotes: 2
Views: 954
Reputation: 790
Apparently Anki wants a url on pasteboard. Method#1 is great, but use NSCachesDirectory instead of hard-coding to desktop:
NSURL* osURL = [[[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil] URLByAppendingPathComponent:@"copiedImage.png"];
Upvotes: 2