2017-05-23 4 views
0

코드 작업을 수행하고 있지만 NSPasteboard에 올바른 접근 방식을 사용하고 있는지 궁금해하며 누구나 최선의 방법을 명확히 설명 할 수 있는지 알아보기 위해 문의하고 있습니다.NSPasteboard 끌기 및 놓기 파일 복사

2012 년 이후로 드래그 앤 드롭에 대해 Apple에서 작성한 문서는 거의없는 것처럼 보이며 그 당시에는 예상치 못한 방식 (특히 샌드 박스 처리 된 앱 사용)이있는 것으로 보입니다. 그것을 구현합니다. 주위를 많이 어지럽히고 나면 드래그 한 대지 보드에서 제공하는 파일 URL이 경로 속성에 액세스 할 때 실제 경로 (URL을 구성하는 익명의 문자열과 대조적으로)를 표시하므로 일반 복사를 사용하여 만들 수 있습니다. FileManager.

제 질문은 여기 제가 올바른 절차를 따르고 있습니까? 페이스트 보드에서 얻은 NSURLURL 유형으로 캐스팅하고 copyItem(at:URL, to:URL)에서 사용하는 것은 작동하지 않습니다. Safari에 동일한 URL을 복사하여 붙여 넣어도 파일을 볼 수 있습니다. 따라서 대신 copyItem(atPath:String, toPath:String)을 사용합니다. 이 점을 더 해결하려면 을 대체하는 URL 유형의 메소드가 있습니까? 있어야 할 것처럼 보인다.

어쨌든 여기에 코드가 있습니다. (드래그 엔트리 안에있는 코드를 무시하십시오. 지금은 테스트를 위해 작동하는 것들을 얻었고, 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 } 
    } 
} 

마지막 요점은 드래그 유형에 등록 할 때 문서 사용 요로 감염을 언급 계속,하지만 난이 확장 얼마나 명확하지 해요 것입니다. NSURLPboardTypeNSFilenamesPboardType을 UTI로 대체해야합니까?

+1

아마도 관련이 없지만 파일 시스템 URL은'fileURLWithPath' 메소드로 초기화되어야합니다 :'URL (fileURLWithPath : NSTemporaryDirectory())'. 그리고'directory'를 non-optional로 선언하고 상수 ('let')로 선언하십시오. – vadian

+0

알림을 보내 주셔서 감사합니다. 이것은 항상 내 마음을 빠져 나가는 것들 중 하나입니다. – sketchyTech

답변

0

애플 개발자 포럼에 대한 조언을 듣고 많은 코드를 버리고 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 
    } 
} 

참고 : 위의 코드를 복사 어떤 끌고 앱의 임시 디렉토리에 파일 (또는 폴더) (포함 파일과 하위 폴더를.) 떨어졌다.

관련 문제