2017-05-23 237 views
0

雖然我有工作代碼,但我對是否採取正確的方法NSPasteboard感到困惑,並且我正在接觸以查看是否有人可以幫助我澄清最佳方法。NSPasteboard複製拖放文件

自2012年以來,似乎沒有任何蘋果公司關於拖放的完整文檔,在那段時間裏,似乎已經被棄用和改變了方式(特別是沙盒應用)執行它。在經歷了許多混亂之後,我發現當您訪問其路徑屬性時,由拖動的粘貼板提供的文件URL顯示其真實路徑(與構成url的匿名字符串數字相反),這使得可以使用常規副本FileManager

我的問題是,我遵循正確的程序嗎?將從粘貼板獲得的NSURL投射到URL類型並在copyItem(at:URL, to:URL)中使用它不起作用(即使將相同的url複製並粘貼到Safari中也能使我查看該文件)。因此我使用copyItem(atPath:String, toPath:String)。爲了進一步解釋這一點,是否有一種替代NSURL(from:NSPasteboard)URL類型的方法?似乎應該有。

無論如何,這裏是我工作的代碼(請忽略draggingEntered內部的代碼:現在,它只是讓事情爲測試工作,而我註冊NSFilenamesPboardType,但忽略它的事實也可以被忽略)。

import Cocoa 

class DraggerView: NSView { 
    let types = [NSURLPboardType, NSFilenamesPboardType] 
    var directory:URL! 

    override init(frame: NSRect) { 
     super.init(frame: frame) 
     register(forDraggedTypes: types) 
     if let dir = URL(string:NSTemporaryDirectory()) 
     { 
      directory = dir 
     } 
    } 


    required init?(coder: NSCoder) { 
     super.init(coder: coder) 
     register(forDraggedTypes: types) 
     if let dir = URL(string:NSTemporaryDirectory()) 
     { 
      directory = dir 
     } 
    } 

    override func draw(_ dirtyRect: NSRect) { 
     super.draw(dirtyRect) 
     NSColor.white.set() 
     NSRectFill(dirtyRect) 
    } 

    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { 
     return NSDragOperation.copy 
    } 


    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool { 

     let pboard = sender.draggingPasteboard() 
     if let types = pboard.types, types.contains(NSURLPboardType) { 


      // add file name to save to loaction 
      if let fileURL = NSURL(from:pboard), let filename = fileURL.lastPathComponent { 
       directory.appendPathComponent(filename) 
       do { 
        try FileManager.default.copyItem(atPath:fileURL.path!, toPath:directory.path) 
       } 
       catch { 
        // something went wrong 
       } 
      } 


      return true 
     } 
     else { return false } 
    } 
} 

最後一點是,文檔不斷提及使用尿路感染的拖累類型註冊時,但我不清楚這到底延伸。我應該用UTI替代NSURLPboardTypeNSFilenamesPboardType嗎?

+1

可能不相關,但必須使用'fileURLWithPath'方法初始化文件系統URL:'URL(fileURLWithPath:NSTemporaryDirectory())'。並聲明'目錄'是非可選的,並且是常量('let')。 – vadian

+0

謝謝你的提醒。這是那些總會滑倒我的想法之一。 – sketchyTech

回答

0

遵循Apple開發人員論壇的建議,我能夠放棄很多代碼並實施readObjects:方法。這大大簡化了事情。

我現在有以下代碼工作(通過使用URL的首選方法而不是路徑)。

import Cocoa 

class DraggerView: NSView { 

    override init(frame: NSRect) { 
     super.init(frame: frame) 
     self.register(forDraggedTypes: [NSURLPboardType]) 
    } 


    required init?(coder: NSCoder) { 
     super.init(coder: coder) 
     self.register(forDraggedTypes: [NSURLPboardType]) 
    } 

    override func draw(_ dirtyRect: NSRect) { 
     super.draw(dirtyRect) 
     NSColor.white.set() 
     NSRectFill(dirtyRect) 
    } 



    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { 
     return NSDragOperation.copy 
    } 


    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool { 
     let pboard = sender.draggingPasteboard() 
     if let urls = pboard.readObjects(forClasses: [NSURL.self], options: [:]) as? [URL] { 
      for url in urls { 
       do { 
        var directory = URL(fileURLWithPath:NSTemporaryDirectory()) 
        directory.appendPathComponent(url.lastPathComponent) 
        try FileManager.default.copyItem(at:url, to:directory) 
       } 
       catch { 
        // something went wrong 
       } 

      } 
     } 


     return true 
    } 
} 

注:上面的代碼複製任意拖放文件(S)或文件夾(S)(包括文件和子文件夾。)您的應用程序的臨時目錄。