iOS11 如何处理放置在自定义 View 中的自定义文件

标签 ios swift

我一直在摆弄 iOS11 的拖放功能。我找到了很多关于标准 UIImage 等的例子,但没有找到关于自定义文件的例子。

拖放部分工作得很好,我用它来拖放自定义文件并将其导入到我的应用中。

问题是我只得到这个文件的数据,我想得到它的名字和扩展名。

我不知道我处理掉落的自定义文件的方式是不是应该如何获取这些信息。如果是这样,您如何从文件中获取此信息?

我有一个符合 NSItemProviderReading 协议(protocol)的 DropFile 类。

class DropFile : NSObject, NSItemProviderReading {
  let fileData:Data?

  required init(data:Data, typeIdentifier:String) {
      fileData = data
  }

  static var readableTypeIdentifiersForItemProvider: [String] {
      var documentTypeArray: [String] = []

      for ext in FileImportProcessHelper.sharedInstance.getImportDocumentType() {
          let UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext as CFString, nil)
          documentTypeArray.append((UTI?.takeRetainedValue() as String?)!)
      }
      return documentTypeArray

  }

  static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> Self {
      return self.init(data: data, typeIdentifier: typeIdentifier)
  }
}

这是我的 ViewController 符合 UIDropInteractionDelegate

// MARK: Handling Drop

@available(iOS 11.0, *)
// We refuse the dropped items based on their UTI
func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {

    var documentTypeArray: [String] = []

    for ext in FileImportProcessHelper.sharedInstance.getImportDocumentType() {
        let UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext as CFString, nil)
        documentTypeArray.append(UTI?.takeRetainedValue() as! String)
    }
    return session.hasItemsConforming(toTypeIdentifiers: documentTypeArray) && session.items.count == 1
}

@available(iOS 11.0, *)
func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
    // Copy file from source app
    return UIDropProposal(operation: .copy)
}

@available(iOS 11.0, *)
func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
    // Consume drag items
    session.loadObjects(ofClass: DropFile.self) { items in
        if let fileItems = items as? [DropFile] {
            DragnDropManager.sharedManager.createDropObject(fileItems: fileItems)
        }
    }
}

然后是我如何编写我的文件。

func createDropObject(fileItems: [DropFile]) {
        let documentsPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
        let inbox = URL(fileURLWithPath: documentsPathString!).appendingPathComponent("UserDropInbox/")

        do {
            try FileManager.default.createDirectory(atPath: inbox.path, withIntermediateDirectories: true, attributes: nil)
        } catch let error as NSError {
            NSLog("Unable to create directory \(error.debugDescription)")
        }

        for file in fileItems {
            do {
                let dropFilePath = inbox.appendingPathComponent("File").appendingPathExtension("pdf")
                try file.fileData?.write(to:dropFilePath)
            } catch {
                NSLog(error as! String)
            }
        }

        FileImportInboxManager.shared.hasReceivedFiles = true;
 }

最佳答案

我承认,这并不简单:

  • 你可以在UIDropSession items成员中列出所有被用户拖动的UIDragItem
  • 这些项目中的每一个都有一个 NSItemProvider itemProvider 成员
  • 此项目提供者有一个可选的 String? suggestedName 成员,该成员可能不是 nil

打印所有 session 项目建议名称的简单循环:

for item in session.items {
   if let name = item.itemProvider.suggestedName {
      print(name)
   }
}

实际上,当文件来自文件应用程序时,它会提供不带扩展名的文件名,但如果您可以轻松访问其 UTI,您可以附加一个接近原始扩展名的扩展名(例如,jpeg 而不是 jpg

关于iOS11 如何处理放置在自定义 View 中的自定义文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47659725/

相关文章:

iOS - 自定义 View frame.size.height 给出 0 值

ios - iPhone如何有效地运行十多个并发线程?

android - Firebase 身份验证获取移动应用用户

ios - PKAddPassButton 文本和图标太大

ios - 当谷歌名称从可选值返回 nil 时应用程序崩溃

ios - 从标签栏 Controller 分支出来?

swift - Swift 代码中 Obj C 枚举的 Xcode 7.3 未声明类型

iphone - 从 xib 移动到 Storyboard时的封装?

php - Swift 2.0 HTML POST(格式不正确)

ios - 无法使用 Facebook 共享链接内容向网址添加描述和标题