I'm perplexed on this one. The only difference between these two code examples is that one uses let, and the other uses guard let.

.readObjects returns [Any]? which may be causing the compiler to get confused and this looks like a bug.

The first example produces [URL]? successfully. The second example with the same code but using guard instead (which you assume would unwrap the optional array to produce [URL]), fails to compile.

Swift 5.2, Xcode 11.3.1

This compiles:

override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
    let files = sender
        .draggingPasteboard
        .readObjects(forClasses: [NSURL.self])?
        .compactMap { $0 as? URL }
    
    print(files)
    
    return true
}

This does NOT compile:

override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
    guard let files = sender
        .draggingPasteboard
        .readObjects(forClasses: [NSURL.self])?
        .compactMap { $0 as? URL }
    else { return false }
    
    print(files)
    
    return true
}

Compiler is confused by the trailing closure. Try surrounding your sender.draggingblahblahblah.compactMap { $0 as? URL } in parentheses, or don't use trailing closures, so that it's clear where it ends

1 Like

Thanks, that seems to resolve it but you'd never guess from the warnings.

Added parens to the compactMap closure as suggested:

override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
    guard let files = sender
        .draggingPasteboard
        .readObjects(forClasses: [NSURL.self])?
        .compactMap({ $0 as? URL })
    else { return false }
    
    print(files)
    
    return true
}
1 Like

The behavior is exactly the same with Xcode 12b3.