Chris Chris - 3 months ago 24
Swift Question

Drag and Drop in Swift - Issues with Registering for Dragged Types?

Background



I am trying to do some simple Drag and Drop in Swift similar to the sample code from Apple for Cocoa Drag and Drop. I am not getting far before I have errors.

I have created a swift class dropView with code at bottom. self.registered for types seems like it worked as I get a long list of image types or the shorter list.

When I set the array for registering dragging types to TIF and jpeg types, I get no response for draggingEntered or draggingUpdated. It seems that I am missing something simple? I have the custom view set to the dropView class.

Separately, I get a host of errors when I drag a file (at least for TIF and jpeg) when the array is set to NSImage.imagePasteBoardTypes() see ** at bottom of post.

Questions



Why is draggingEntered or draggingUpdated not being called?

Other questions:

Am I registering for dragged types correctly?
Is the array in the right format?
Is the NSDraggingDestination property bit at the top of the file in the right spot?

Code



import Cocoa

class dropView: NSView, NSDraggingDestination {

init(frame: NSRect) {
super.init(frame: frame)
//let theArray = [NSImage.imagePasteboardTypes()]
let theArray = ["NSTypedFilenamesPboardType:jpg",
"NSTypedFilenamesPboardType:JPG",
"NSTypedFilenamesPboardType:jpeg",
"NSTypedFilenamesPboardType:JPEG",
"NSTypedFilenamesPboardType:jpe",
"NSTypedFilenamesPboardType:TIF"]

registerForDraggedTypes(theArray)
println("INIT and REGISTER")
println(self.registeredDraggedTypes)
}

override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)

// Drawing code here.
}


override func draggingEntered(sender: NSDraggingInfo!) -> NSDragOperation {
println("Dragging Entered")
return NSDragOperation.Copy
}

override func draggingUpdated(sender: NSDraggingInfo!) -> NSDragOperation {
println("UPDATED")
return NSDragOperation.Copy
}

}


** Errors when NSImage.imagePasteBoardTypes()



2014-06-21 11:34:38.728 DragAndDrop[96606:303] -[__NSArrayM length]: unrecognized selector sent to instance 0x610000049d80
2014-06-21 11:34:38.729 DragAndDrop[96606:303] -[__NSArrayM length]: unrecognized selector sent to instance 0x610000049d80
2014-06-21 11:34:38.730 DragAndDrop[96606:303] (
0 CoreFoundation 0x00007fff8ddaf25c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff83a5de75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8ddb212d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff8dd0d322 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff8dd0cea8 _CF_forwarding_prep_0 + 120
5 LaunchServices 0x00007fff8aee1b0a XCFStringHashCaseInsensitive + 111
6 CoreFoundation 0x00007fff8dc6afd8 CFBasicHashFindBucket + 1032
7 CoreFoundation 0x00007fff8dc989c9 CFSetGetValueIfPresent + 121
8 CoreFoundation 0x00007fff8dc9892c -[__NSCFSet member:] + 28
9 CoreFoundation 0x00007fff8dccb008 -[NSSet containsObject:] + 24
10 CoreFoundation 0x00007fff8dd18fcf -[NSSet intersectsSet:] + 735
11 AppKit 0x00007fff86c645ff -[NSView(NSDrag) _hitTest:dragTypes:] + 221
12 AppKit 0x00007fff86c645d2 -[NSView(NSDrag) _hitTest:dragTypes:] + 176
13 AppKit 0x00007fff86c645d2 -[NSView(NSDrag) _hitTest:dragTypes:] + 176
14 AppKit 0x00007fff86c6438c -[NSWindow(NSDrag) _findDragTargetFrom:] + 111
15 AppKit 0x00007fff86c63280 NSCoreDragTrackingProc + 476
16 HIServices 0x00007fff8b8a05a3 DoEnterLeaveHandler + 389
17 HIServices 0x00007fff8b8a2fdd CoreDragMessageHandler + 1741
18 CoreFoundation 0x00007fff8dd5ace8 __CFMessagePortPerform + 760
19 CoreFoundation 0x00007fff8dce08d9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
20 CoreFoundation 0x00007fff8dce084e __CFRunLoopDoSource1 + 478
21 CoreFoundation 0x00007fff8dcd1886 __CFRunLoopRun + 1830
22 CoreFoundation 0x00007fff8dcd0f25 CFRunLoopRunSpecific + 309
23 HIToolbox 0x00007fff8b908a0d RunCurrentEventLoopInMode + 226
24 HIToolbox 0x00007fff8b9087b7 ReceiveNextEventCommon + 479
25 HIToolbox 0x00007fff8b9085bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
26 AppKit 0x00007fff8695726e _DPSNextEvent + 1434
27 AppKit 0x00007fff869568bb -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
28 AppKit 0x00007fff8694a9bc -[NSApplication run] + 553
29 AppKit 0x00007fff869357a3 NSApplicationMain + 940
30 DragAndDrop 0x00000001000033fd top_level_code + 109
31 DragAndDrop 0x000000010000343a main + 42
32 libdyld.dylib 0x00007fff8e1925fd start + 1
33 ??? 0x0000000000000003 0x0 + 3
)
2014-06-21 11:34:40.729 DragAndDrop[96606:303] -[__NSArrayM length]: unrecognized selector sent to instance 0x610000049d80
2014-06-21 11:34:40.730 DragAndDrop[96606:303] -[__NSArrayM length]: unrecognized selector sent to instance 0x610000049d80
2014-06-21 11:34:40.731 DragAndDrop[96606:303] (
0 CoreFoundation 0x00007fff8ddaf25c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff83a5de75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8ddb212d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff8dd0d322 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff8dd0cea8 _CF_forwarding_prep_0 + 120
5 LaunchServices 0x00007fff8aee1b0a XCFStringHashCaseInsensitive + 111
6 CoreFoundation 0x00007fff8dc6afd8 CFBasicHashFindBucket + 1032
7 CoreFoundation 0x00007fff8dc989c9 CFSetGetValueIfPresent + 121
8 CoreFoundation 0x00007fff8dc9892c -[__NSCFSet member:] + 28
9 CoreFoundation 0x00007fff8dccb008 -[NSSet containsObject:] + 24
10 CoreFoundation 0x00007fff8dd18fcf -[NSSet intersectsSet:] + 735
11 AppKit 0x00007fff86c645ff -[NSView(NSDrag) _hitTest:dragTypes:] + 221
12 AppKit 0x00007fff86c645d2 -[NSView(NSDrag) _hitTest:dragTypes:] + 176
13 AppKit 0x00007fff86c645d2 -[NSView(NSDrag) _hitTest:dragTypes:] + 176
14 AppKit 0x00007fff86c6438c -[NSWindow(NSDrag) _findDragTargetFrom:] + 111
15 AppKit 0x00007fff86c63280 NSCoreDragTrackingProc + 476
16 HIServices 0x00007fff8b89fca4 DoTrackingMessage + 370
17 HIServices 0x00007fff8b8a2b36 CoreDragMessageHandler + 550
18 CoreFoundation 0x00007fff8dd5ace8 __CFMessagePortPerform + 760
19 CoreFoundation 0x00007fff8dce08d9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
20 CoreFoundation 0x00007fff8dce084e __CFRunLoopDoSource1 + 478
21 CoreFoundation 0x00007fff8dcd1886 __CFRunLoopRun + 1830
22 CoreFoundation 0x00007fff8dcd0f25 CFRunLoopRunSpecific + 309
23 HIToolbox 0x00007fff8b908a0d RunCurrentEventLoopInMode + 226
24 HIToolbox 0x00007fff8b9087b7 ReceiveNextEventCommon + 479
25 HIToolbox 0x00007fff8b9085bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
26 AppKit 0x00007fff8695726e _DPSNextEvent + 1434
27 AppKit 0x00007fff869568bb -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
28 AppKit 0x00007fff8694a9bc -[NSApplication run] + 553
29 AppKit 0x00007fff869357a3 NSApplicationMain + 940
30 DragAndDrop 0x00000001000033fd top_level_code + 109
31 DragAndDrop 0x000000010000343a main + 42
32 libdyld.dylib 0x00007fff8e1925fd start + 1
33 ??? 0x0000000000000003 0x0 + 3
)

Answer

Regarding the crash

Separately, I get a host of errors when I drag a file (at least for TIF and jpeg) when the array is set to NSImage.imagePasteBoardTypes() see ** at bottom of post.

NSImage.imagePasteboardTypes() already returns an array, so using it like this:

let theArray = NSImage.imagePasteboardTypes()

instead of like this

let theArray = [NSImage.imagePasteboardTypes()]

will fix the crash.

Regarding NSDragDestination

Why is draggingEntered or draggingUpdated not being called?

If you're dragging from Finder, you probably want let types = [NSFilenamesPboardType]. The code you have means you have to place data onto the pasteboard yourself -- Finder doesn't put file contents onto the pasteboard, it puts filenames.

Is the NSDraggingDestination property bit at the top of the file in the right spot?

Yep! : NSDraggingDestination tells Swift that you're about to implement the protocol.

Working example

// Public domain
import Cocoa

class DragView: NSView, NSDraggingDestination {
    init(frame: NSRect) {
        super.init(frame: frame)
        let types = [NSFilenamesPboardType]
        registerForDraggedTypes(types)
        println(self.registeredDraggedTypes)
    }

    override func drawRect(dirtyRect: NSRect)  {
        super.drawRect(dirtyRect)
        NSColor.whiteColor().set()
        NSRectFill(dirtyRect)
    }

    override func draggingEntered(sender: NSDraggingInfo!) -> NSDragOperation  {
        println("hello")
        return NSDragOperation.Copy
    }
}