web-dev-qa-db-ja.com

Swift 4:NSFilenamesPboardTypeは使用できません。代わりにregisterForDraggedTypesに何を使用しますか?

Swift4に移行した後、次のコードでコンパイルエラーが発生します。

public final class MediaItemView: NSView {

   public override init(frame frameRect: NSRect) {
      super.init(frame: frameRect)

      // error: 'NSFilenamesPboardType' is unavailable in Swift:
      // use 'NSPasteboard.writeObjects(_:)' with file URLs
      let draggedTypes: [NSPasteboard.PasteboardType] = [NSFilenamesPboardType]
      registerForDraggedTypes(draggedTypes)
   }
}

Swift4のNSFilenamesPboardTypeの代替品は何ですか? file nameのドラッグタイプ(私の場合はmp3、wav、aiff、...ファイル)をSwift4に登録する方法は?

ありがとう!

15
Vlad

この拡張機能との下位互換性を解決しました:

extension NSPasteboard.PasteboardType {

    static let backwardsCompatibleFileURL: NSPasteboard.PasteboardType = {

            if #available(OSX 10.13, *) {
                return NSPasteboard.PasteboardType.fileURL
            } else {
                return NSPasteboard.PasteboardType(kUTTypeFileURL as String)
            }

    } ()

}

つまり、NSPasteboard.PasteboardType.backwardsCompatibleFileURLを使用できます

17
Mark Bridges

私はこれを解決策として使用します

    //Temp solution for this
    let NSFilenamesPboardTypeTemp = NSPasteboard.PasteboardType("NSFilenamesPboardType")

    self.zipView.registerForDraggedTypes([NSFilenamesPboardTypeTemp])

これはAppleのバグのようで、APIを10.13でのみ動作するものとしてマークしました。

i fire a bug to Apple:)

11
slboat

非推奨の変数NSFilenamesPboardTypeに対してここに示されている創造的な回避策が好きです。この質問を調べた後、非推奨ではない同等のアプローチで前進する方法は、readObjects(forClasses:options:)を使用することです。これは、将来のmacOSで実行できるWRTの安全性も高くなります。次の例のように実装され、ストーリーボードにNSViewが登録されていることに基づいて、Swift 4.1でテストされます。

override func awakeFromNib()
{
    registerForDraggedTypes([.fileURL])
}

override func draggingEnded(_ sender: NSDraggingInfo)
{
    sender
        .draggingPasteboard()
        .readObjects(forClasses: [NSURL.self],
                     options: nil)?
        .forEach
        {
            // Do something with the file paths.
            if let url = $0 as? URL { print(url.path) }
        }
}

readObjectsのクラス配列パラメーターはタイプ[AnyClass]であるため、NSURLの代わりにURLを使用する理由です。

8
Daniel Zhang

私も同じ問題に直面しており、私の解決策はkUTTypeURLでカスタム_NSPasteboard.PasteboardType_を作成することです。これが最も適切な方法であるかどうかはわかりませんが(おそらくそうではないと思います)、少なくとも一時的な回避策としては機能します。

_    let draggedType = NSPasteboard.PasteboardType(kUTTypeURL as String)
    self.tableView?.registerForDraggedTypes([draggedType])
_

さらに、新しい_NSPasteboard.PasteboardType_には.fileNameType(forPathExtension: "foo")メソッドがあります。試してみてください。しかし、どういうわけか、私の場合は機能しません。

3
1024jp

マークブリッジスの答えslboatの答え の組み合わせを使用して、これは私が思いついた解決策です:

extension NSPasteboard.PasteboardType {

    /// The name of a file or directory
    static let fileName: NSPasteboard.PasteboardType = {
        return NSPasteboard.PasteboardType("NSFilenamesPboardType")
    }()
}

これは私のテストでは期待どおりに機能します。

1
hisaac

Swift4、Swift5

一時的な回避策の一部ですが、Swift4/5で機能しています:

var chromeType: NSPasteboard.PasteboardType { return NSPasteboard.PasteboardType.init(rawValue: "org.chromium.drag-dummy-type") }
var finderNode: NSPasteboard.PasteboardType { return NSPasteboard.PasteboardType.init(rawValue: "com.Apple.Finder.node") }
var fileURLs: NSPasteboard.PasteboardType { return NSPasteboard.PasteboardType.init(rawValue: "NSFilenamesPboardType") }
var webarchive: NSPasteboard.PasteboardType { return NSPasteboard.PasteboardType.init(rawValue: "com.Apple.webarchive") }

次に、

var acceptableTypes: Set<NSPasteboard.PasteboardType> { return [.URL, .fileURL, .pdf, .png, .rtf, .rtfd, .tiff, finderNode, webarchive] }

次に、ビューで使用したロードメソッド:

//  Intercept drags
registerForDraggedTypes(Array(acceptableTypes))
0
slashlos

Swift 5

//MARK:- Managing a Dragging Session After an Image Is Released

    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
        let fetched = sender.draggingPasteboard.readObjects(forClasses:  [NSURL.self], options: nil)?
            .map({ (argv) -> String? in
                guard let url = argv as? URL else{
                    return nil
                }
                return url.path
            }).compactMap({$0})

        guard let result = fetched else{
            return false
        }
        // handle the result
        print(result)
        return true
    }
0
dengST30