2017-12-27 8 views
1

이전에 Mail.app에서 전자 메일 (/ - 스레드)을 삭제 한 & 전자 메일 메타 데이터를 발견하기 위해 다음을 사용했습니다. 는 janky의macOS에서 약속 된 전자 메일 받기 10.12 +

 if let filenames = draggingInfo.namesOfPromisedFilesDropped(atDestination: URL(fileURLWithPath: destinationDir!)) { 
      /// TODO: in future implementation Mail might return multiple filenames here. 
      ///   So we will keep this structure to iterate the filenames 
      //var aPaths: [String] = [] 
      //for _ in filenames { 
       if let aPath = pb.string(forType: "com.apple.pasteboard.promised-file-url") { 
        return aPath 
       } 
      //} 
      //return aPaths 
     } 

종류,하지만 "com.apple.pasteboard.promised-file-url" 만하는 상황에서 공급 된 이후 그것은했다.

그러나 10.12 이후 API가 변경된 것 같습니다. WWDC2016 talk을 보면 Apple이 NSFilePromiseReceiver를 사용하기를 원합니다. 몇 가지 접근법을 시도했지만 팝업으로 약속 된 파일 URL을 가져올 수 없습니다.

설정 :

class DropzoneView: NSView { 

var supportedDragTypes = [ 

    kUTTypeURL as String, // For any URL'able types 
    "public.url-name", // E-mail title 
    "public.utf8-plain-text", // Plaintext item/E-mail thread title/calendar event date placeholder 
    "com.apple.pasteboard.promised-file-content-type", // Calendar event/Web URL/E-mail thread type detection 
    "com.apple.mail.PasteboardTypeMessageTransfer", // E-mail thread detection 
    "NSPromiseContentsPboardType", // E-mail thread meta-data 
    "com.apple.pasteboard.promised-file-url", // E-mail thread meta-data 
    "com.apple.NSFilePromiseItemMetaData" // E-mail thread meta-data 
] 

override func viewDidMoveToSuperview() { 
    var dragTypes = self.supportedDragTypes.map { (type) -> NSPasteboard.PasteboardType in 
     return NSPasteboard.PasteboardType(type) 
    } // Experiment: 
    dragTypes.append(NSPasteboard.PasteboardType.fileContentsType(forPathExtension: "eml")) 
    dragTypes.append(NSPasteboard.PasteboardType.fileContentsType(forPathExtension: "emlx")) 

    self.registerForDraggedTypes(dragTypes) 
} 

} 

처리 :

extension DropzoneView { 

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

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

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

    let pasteboard: NSPasteboard = sender.draggingPasteboard() 
      guard let filePromises = pasteboard.readObjects(forClasses: [NSFilePromiseReceiver.self], options: nil) as? [NSFilePromiseReceiver] else { 
     return false 
    } 

    var files = [Any]() 
    var errors = [Error]() 

    let filePromiseGroup = DispatchGroup() 
    let operationQueue = OperationQueue() 
    let newTempDirectoryURL = URL(fileURLWithPath: (NSTemporaryDirectory() + (UUID().uuidString) + "/"), isDirectory: true) 
    do { 
     try FileManager.default.createDirectory(at: newTempDirectoryURL, withIntermediateDirectories: true, attributes: nil) 
    } 
    catch { 
     return false 
    } 

    // Async attempt, either times out after a minute or so (Error Domain=NSURLErrorDomain Code=-1001 "(null)") or gives 'operation cancelled' error 
    filePromises.forEach({ filePromiseReceiver in 
     filePromiseGroup.enter() 
     filePromiseReceiver.receivePromisedFiles(atDestination: newTempDirectoryURL, 
               options: [:], 
               operationQueue: operationQueue, 
               reader: { (url, error) in 
                Swift.print(url) 
                if let error = error { 
                 errors.append(error) 
                } 
                else if url.isFileURL { 
                 files.append(url) 
                } 
                else { 
                 Swift.print("No loadable URLs found") 
                } 

                filePromiseGroup.leave() 
     }) 
    }) 

    filePromiseGroup.notify(queue: DispatchQueue.main, 
          execute: { 
           // All done, check your files and errors array 
           Swift.print("URLs: \(files)") 
           Swift.print("errors: \(errors)") 
    }) 

    Swift.print("URLs: \(files)") 

    return true 
} 

다른 시도 : 모든 포인터는 크게 감상 할 수

// returns nothing 
    if let filenames = pasteboard.propertyList(forType: NSPasteboard.PasteboardType(rawValue: "com.apple.pasteboard.promised-file-url")) as? NSArray { 
     Swift.print(filenames) 
    } 

    // doesn't result in usable URLs either 
    if let urls = pasteboard.readObjects(forClasses: [NSPasteboardItem.self /*NSURL.self, ???*/], options: [:]) as? [... 

.

+0

이 작업을 진행할 수 있었습니까? – iphaaw

답변

1

나는 "팝 아웃"파일을 얻을 수 있었지만 그 파일에 대한 세부 정보는 얻을 수 없습니다. 즉시 전송 한 다음 60 초 동안 정지하여 오류 메시지를 반환합니다.

어쩌면 그것은 단서이지만 commentExtension 메서드는 주석 처리되고 true로 설정되지 않는 한 결코 반환되지 않습니다.

class DropView: NSView 
{ 
    var filePath: String? 

    required init?(coder: NSCoder) { 
     super.init(coder: coder) 

     self.wantsLayer = true 
     self.layer?.backgroundColor = NSColor.red.cgColor 

     registerForDraggedTypes([NSPasteboard.PasteboardType 
      .fileNameType(forPathExtension: ".eml"), NSPasteboard.PasteboardType.filePromise]) 
    } 

    override func draw(_ dirtyRect: NSRect) { 
     super.draw(dirtyRect) 
     // Drawing code here. 
    } 

    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { 
     if checkExtension(sender) == true 
     { 
      self.layer?.backgroundColor = NSColor.blue.cgColor 
      return .copy 
     } 
     else 
     { 
      return NSDragOperation() 
     } 
    } 

    fileprivate func checkExtension(_ drag: NSDraggingInfo) -> Bool 
    { 
     return true 
//  guard let board = drag.draggingPasteboard().propertyList(forType: NSPasteboard.PasteboardType(rawValue: "com.apple.mail.PasteboardTypeMessageTransfer")) as? NSArray, 
//   let path = board[0] as? String 
//   else 
//   { 
//    return false 
//   } 
// 
//  let suffix = URL(fileURLWithPath: path).pathExtension 
//  for ext in self.expectedExt 
//  { 
//   if ext.lowercased() == suffix 
//   { 
//    return true 
//   } 
//  } 
//  return false 
    } 

    override func draggingExited(_ sender: NSDraggingInfo?) 
    { 
     self.layer?.backgroundColor = NSColor.gray.cgColor 
    } 

    override func draggingEnded(_ sender: NSDraggingInfo) 
    { 
     self.layer?.backgroundColor = NSColor.gray.cgColor 
    } 

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

     let pasteboard: NSPasteboard = sender.draggingPasteboard() 

     guard let filePromises = pasteboard.readObjects(forClasses: [NSFilePromiseReceiver.self], options: nil) as? [NSFilePromiseReceiver] else { 
      return false 
     } 

     print ("Files dropped") 
     var files = [URL]() 

     let filePromiseGroup = DispatchGroup() 
     let operationQueue = OperationQueue() 
     let destURL = URL(fileURLWithPath: "/Users/andrew/Temporary", isDirectory: true) 
     print ("Destination URL: \(destURL)") 

     filePromises.forEach ({ filePromiseReceiver in 
      print (filePromiseReceiver) 
      filePromiseGroup.enter() 

      filePromiseReceiver.receivePromisedFiles(atDestination: destURL, 
                options: [:], 
                operationQueue: operationQueue, 
                reader: 
                { (url, error) in 
                 print ("Received URL: \(url)") 
                 if let error = error 
                 { 
                  print ("Error: \(error)") 
                 } 
                 else 
                 { 
                  files.append(url) 
                 } 
                 print (filePromiseReceiver.fileNames, filePromiseReceiver.fileTypes) 

                 filePromiseGroup.leave() 
                }) 
     }) 

     filePromiseGroup.notify(queue: DispatchQueue.main, 
           execute: 
           { 
            print ("Files: \(files)") 
            print ("Done") 
           }) 
     return true 
    } 

} 

이의 출력이 조금 이상해 :

는 희망이 길 아래에 약간 깡통을 걷어차하는 데 도움이됩니다. url 변수는 내가 전달한 디렉토리의 이름을 반복합니다.

Files dropped 
Destination URL: file:///Users/andrew/Temporary/ 
<NSFilePromiseReceiver: 0x6000000a1aa0> 

** one minute gap ** 

Received URL: file:///Users/andrew/Temporary/Temporary/ 
Error: Error Domain=NSURLErrorDomain Code=-1001 "(null)" 
["Temporary"] ["com.apple.mail.email"] 
Files: [] 
Done 
+0

감사합니다. @iphaaw, 줄거리가 두꺼워졌습니다! 나는 실제로 Apple에 지원 요청을 제출했고 그들이 "문제를 알고 있지만 현재 해결되지 않거나 해결 방법이나 표시가 없음을 알리는 메시지로 환불을받습니다."나는 앱에서 내 앱을 철회했습니다. 저장하고 non-osx 프로젝트로 옮겼습니다. –

관련 문제