macosdrag-and-dropprotocolsnsdraggingdestination

What methods are obligatory in the NSDraggingDestination protocol?


In the Docs of the protocol NSDraggingDestination, it says that:

A set of methods that the destination object (or recipient) of a dragged image must implement.

Then follows nine methods. But I only implemented 3 out of those nine methods (in my NSView): draggingEntered:, prepareForDragOperation: and performDragOperation:.

It compiles and runs without warnings or crashes. The docs do not say that some methods are obligatory while others are optional, so how come that it works?

#import "Common.h"

@interface StageView : NSView <NSDraggingDestination>

@end

#import "StageView.h"

@implementation StageView

-(void)awakeFromNib {
    // we want pasteboard to hold a single URL (See Drag and Drop Programming Topics)
    NSLog(@"--registerForDraggedTypes");
    [self registerForDraggedTypes:@[NSURLPboardType]];
}


#pragma mark - DragAndDrop

-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
    NSLog(@"--draggingEntered");
    return NSDragOperationCopy;
}

-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender {
    NSLog(@"--prepareForDragOperation");
    //check to see if we can accept the data
    return YES;
}

// method that should handle the drop data
-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
    NSLog(@"--performDragOperation");
    NSInteger numFiles = sender.numberOfValidItemsForDrop;
    CGPoint loc = sender.draggingLocation;
    NSURL *fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
    NSString *ext = [fileURL pathExtension];

    if ([ext isEqualToString:@"mov"] && numFiles == 1) {
        [self handleVideo:loc url:fileURL];
        return YES;
    }

    return NO;
}


#pragma mark - Handle Video

-(void)handleVideo:(CGPoint)loc url:(NSURL *)fileURL {
    NSLog(@"--handleVideo");
    // ...
}

@end

Solution

  • If you look at the implementation, you will see, that, in fact, all of the methods are optional:

    public protocol NSDraggingDestination : NSObjectProtocol {
        optional public func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation
    
        optional public func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation
    
        optional public func draggingExited(_ sender: NSDraggingInfo?)
    
        optional public func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool
    
        optional public func performDragOperation(_ sender: NSDraggingInfo) -> Bool
    
        optional public func concludeDragOperation(_ sender: NSDraggingInfo?)
    
        optional public func draggingEnded(_ sender: NSDraggingInfo)
    
        optional public func wantsPeriodicDraggingUpdates() -> Bool
    
        optional public func updateDraggingItemsForDrag(_ sender: NSDraggingInfo?)
    }
    

    The wording of the documentation provided by Apple is misleading, you should interpret it as "you must implement them if you want to handle those actions".