我一直在摆弄 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/