实施文档选择器

问题描述 投票:0回答:10

我想在我的 iOS 应用程序中选择任何类型的文件(.pdf、.docs、.xlsx、.jpeg、.txt、.rtf、等)。单击 Upload 按钮时,我希望我的应用程序打开一个目录并选择文件 (DocumentsPicker

)

@IBAction pickDocument(sender: UIButton) { //Open Document Picker }
有什么方法可以在 Swift 中做到这一点吗?

ios swift uidocumentpickervc
10个回答
119
投票

iOS 17 略有更新

仅添加...

import UIKit // nothing else class Job: UIViewController, UIDocumentPickerDelegate { // delete "UIDocumentMenuDelegate"
然后...

@IBAction func tapSendFile() { let pdfs = UTType.types(tag: "pdf", tagClass: UTTagClass.filenameExtension, conformingTo: nil) let txts = UTType.types(tag: "txt", tagClass: UTTagClass.filenameExtension, conformingTo: nil) // as many of those as you wish, then: let doxy = UIDocumentPickerViewController( forOpeningContentTypes: pdfs + txts) doxy.delegate = self self.present(doxy, animated: true, completion: nil) }
最新语法:

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { print("IT WORKED") }


iOS 14 更新:您不需要任何功能。只需创建一个具有适当类型的 UIDocumentPickerViewController

,实现委托,就完成了。

import UIKit import MobileCoreServices import UniformTypeIdentifiers func selectFiles() { let types = UTType.types(tag: "json", tagClass: UTTagClass.filenameExtension, conformingTo: nil) let documentPickerController = UIDocumentPickerViewController( forOpeningContentTypes: types) documentPickerController.delegate = self self.present(documentPickerController, animated: true, completion: nil) }


根据您的项目功能,启用

iCloud

Key-Sharing

在您的类中导入

MobileCoreServices

,然后在您的 
UIViewController
 中扩展以下三个类:

UIDocumentMenuDelegate,UIDocumentPickerDelegate,UINavigationControllerDelegate
实现以下功能:

public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { guard let myURL = urls.first else { return } print("import result : \(myURL)") } public func documentMenu(_ documentMenu:UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) { documentPicker.delegate = self present(documentPicker, animated: true, completion: nil) } func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { print("view was cancelled") dismiss(animated: true, completion: nil) }
你如何称呼这一切?将以下代码添加到您的点击函数中:

func clickFunction(){ let importMenu = UIDocumentMenuViewController(documentTypes: [String(kUTTypePDF)], in: .import) importMenu.delegate = self importMenu.modalPresentationStyle = .formSheet self.present(importMenu, animated: true, completion: nil) }
单击您的按钮。将弹出以下菜单..

以 Dropbox 为例。单击任何项目后。您将被重定向回您的应用程序,并且 URL 将记录在您的终端中。

根据您的需要操作文档类型。在我的应用程序中,用户仅允许使用 Pdf。所以,适合自己吧。

kUTTypePDF

kUTTypePNG
kUTTypeJPEG
...

如果您想自定义自己的菜单栏。添加以下代码并在处理程序中自定义您自己的函数

importMenu.addOption(withTitle: "Create New Document", image: nil, order: .first, handler: { print("New Doc Requested") })

享受它。


40
投票
您可以使用

UIDocumentPickerViewController

 从“文件”应用程序或 iCloud Drive 获取文件。

  1. Key-value storage
     功能激活 
    iCloud Documents
    iCloud

  1. 在要打开文档选择器的视图控制器上导入以下框架:

    import MobileCoreServices // For iOS 14+ import UniformTypeIdentifiers
    
    
  2. UIDocumentPickerDelegate

    实现以下方法:

    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { // you get from the urls parameter the urls from the files selected }
    
    
  3. 创建一个

    UIDocumentPickerViewController

     以显示文件选择器或 iCloud Drive:

    // Use this code if your are developing prior iOS 14 let types: [String] = [kUTTypePDF as String] let documentPicker = UIDocumentPickerViewController(documentTypes: types, in: .import) documentPicker.delegate = self documentPicker.modalPresentationStyle = .formSheet self.present(documentPicker, animated: true, completion: nil) // For iOS 14+ let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.item], asCopy: false) documentPicker.delegate = self documentPicker.modalPresentationStyle = .formSheet self.present(documentPicker, animated: true, completion: nil)
    
    
如果您希望用户可以将更多类型的文件导入到您的应用程序中,您必须在

UTType

 
types
 中添加更多 
NSArray
。要查看所有可用的类型,您可以查看
UTType Docs

当文档选择器在 iOS 11 上打开并且您尝试选择 Google 云端硬盘中的文件时,该文件可能由于错误而被禁用:

http://www.openradar.me/24187873


24
投票

UIDocumentMenuViewController

 自 iOS11 起已弃用。当从模态视图控制器呈现时,我还发现它有问题。
这是使用选择器的直接方法:

import MobileCoreServices private func attachDocument() { let types = [kUTTypePDF, kUTTypeText, kUTTypeRTF, kUTTypeSpreadsheet] let importMenu = UIDocumentPickerViewController(documentTypes: types as [String], in: .import) if #available(iOS 11.0, *) { importMenu.allowsMultipleSelection = true } importMenu.delegate = self importMenu.modalPresentationStyle = .formSheet present(importMenu, animated: true) } extension AViewController: UIDocumentPickerDelegate, UINavigationControllerDelegate { func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { viewModel.attachDocuments(at: urls) } func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { controller.dismiss(animated: true, completion: nil) } }

像往常一样,不要忘记添加 iCloud 支持:


9
投票
UIDocumentPickerViewController(documentTypes: [String], in: UIDocumentPickerMode) 在 iOS 14.0 中已被

弃用

现在是 UIDocumentPickerViewController(forOpeningContentTypes:

[UTType]

)

ContentTypes 可以是以下任意项或以下项的组合:

UTType.image, UTType.text, UTType.plainText, UTType.utf8PlainText, UTType.utf16ExternalPlainText, UTType.utf16PlainText, UTType.delimitedText, UTType.commaSeparatedText, UTType.tabSeparatedText, UTType.utf8TabSeparatedText, UTType.rtf, UTType.pdf, UTType.webArchive, UTType.image, UTType.jpeg, UTType.tiff, UTType.gif, UTType.png, UTType.bmp, UTType.ico, UTType.rawImage, UTType.svg, UTType.livePhoto, UTType.movie, UTType.video, UTType.audio, UTType.quickTimeMovie, UTType.mpeg, UTType.mpeg2Video, UTType.mpeg2TransportStream, UTType.mp3, UTType.mpeg4Movie, UTType.mpeg4Audio, UTType.avi, UTType.aiff, UTType.wav, UTType.midi, UTType.archive, UTType.gzip, UTType.bz2, UTType.zip, UTType.appleArchive, UTType.spreadsheet, UTType.epub
这对我来说是这样的:

let supportedTypes = [myArrayFromAnyOfTheAbove] func openDocument() { let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes, asCopy: true) documentPicker.delegate = self documentPicker.allowsMultipleSelection = false documentPicker.shouldShowFileExtensions = true present(documentPicker, animated: true, completion: nil) }
    

4
投票
let docsTypes = ["public.text", "com.apple.iwork.pages.pages", "public.data", "kUTTypeItem", "kUTTypeContent", "kUTTypeCompositeContent", "kUTTypeData", "public.database", "public.calendar-event", "public.message", "public.presentation", "public.contact", "public.archive", "public.disk-image", "public.plain-text", "public.utf8-plain-text", "public.utf16-external-plain-​text", "public.utf16-plain-text", "com.apple.traditional-mac-​plain-text", "public.rtf", "com.apple.ink.inktext", "public.html", "public.xml", "public.source-code", "public.c-source", "public.objective-c-source", "public.c-plus-plus-source", "public.objective-c-plus-​plus-source", "public.c-header", "public.c-plus-plus-header", "com.sun.java-source", "public.script", "public.assembly-source", "com.apple.rez-source", "public.mig-source", "com.apple.symbol-export", "com.netscape.javascript-​source", "public.shell-script", "public.csh-script", "public.perl-script", "public.python-script", "public.ruby-script", "public.php-script", "com.sun.java-web-start", "com.apple.applescript.text", "com.apple.applescript.​script", "public.object-code", "com.apple.mach-o-binary", "com.apple.pef-binary", "com.microsoft.windows-​executable", "com.microsoft.windows-​dynamic-link-library", "com.sun.java-class", "com.sun.java-archive", "com.apple.quartz-​composer-composition", "org.gnu.gnu-tar-archive", "public.tar-archive", "org.gnu.gnu-zip-archive", "org.gnu.gnu-zip-tar-archive", "com.apple.binhex-archive", "com.apple.macbinary-​archive", "public.url", "public.file-url", "public.url-name", "public.vcard", "public.image", "public.fax", "public.jpeg", "public.jpeg-2000", "public.tiff", "public.camera-raw-image", "com.apple.pict", "com.apple.macpaint-image", "public.png", "public.xbitmap-image", "com.apple.quicktime-image", "com.apple.icns", "com.apple.txn.text-​multimedia-data", "public.audiovisual-​content", "public.movie", "public.video", "com.apple.quicktime-movie", "public.avi", "public.mpeg", "public.mpeg-4", "public.3gpp", "public.3gpp2", "public.audio", "public.mp3", "public.mpeg-4-audio", "com.apple.protected-​mpeg-4-audio", "public.ulaw-audio", "public.aifc-audio", "public.aiff-audio", "com.apple.coreaudio-​format", "public.directory", "public.folder", "public.volume", "com.apple.package", "com.apple.bundle", "public.executable", "com.apple.application", "com.apple.application-​bundle", "com.apple.application-file", "com.apple.deprecated-​application-file", "com.apple.plugin", "com.apple.metadata-​importer", "com.apple.dashboard-​widget", "public.cpio-archive", "com.pkware.zip-archive", "com.apple.webarchive", "com.apple.framework", "com.apple.rtfd", "com.apple.flat-rtfd", "com.apple.resolvable", "public.symlink", "com.apple.mount-point", "com.apple.alias-record", "com.apple.alias-file", "public.font", "public.truetype-font", "com.adobe.postscript-font", "com.apple.truetype-​datafork-suitcase-font", "public.opentype-font", "public.truetype-ttf-font", "public.truetype-collection-​font", "com.apple.font-suitcase", "com.adobe.postscript-lwfn​-font", "com.adobe.postscript-pfb-​font", "com.adobe.postscript.pfa-​font", "com.apple.colorsync-profile", "public.filename-extension", "public.mime-type", "com.apple.ostype", "com.apple.nspboard-type", "com.adobe.pdf", "com.adobe.postscript", "com.adobe.encapsulated-​postscript", "com.adobe.photoshop-​image", "com.adobe.illustrator.ai-​image", "com.compuserve.gif", "com.microsoft.bmp", "com.microsoft.ico", "com.microsoft.word.doc", "com.microsoft.excel.xls", "com.microsoft.powerpoint.​ppt", "com.microsoft.waveform-​audio", "com.microsoft.advanced-​systems-format", "com.microsoft.windows-​media-wm", "com.microsoft.windows-​media-wmv", "com.microsoft.windows-​media-wmp", "com.microsoft.windows-​media-wma", "com.microsoft.advanced-​stream-redirector", "com.microsoft.windows-​media-wmx", "com.microsoft.windows-​media-wvx", "com.microsoft.windows-​media-wax", "com.apple.keynote.key", "com.apple.keynote.kth", "com.truevision.tga-image", "com.sgi.sgi-image", "com.ilm.openexr-image", "com.kodak.flashpix.image", "com.j2.jfx-fax", "com.js.efx-fax", "com.digidesign.sd2-audio", "com.real.realmedia", "com.real.realaudio", "com.real.smil", "com.allume.stuffit-archive", "org.openxmlformats.wordprocessingml.document", "com.microsoft.powerpoint.​ppt", "org.openxmlformats.presentationml.presentation", "com.microsoft.excel.xls", "org.openxmlformats.spreadsheetml.sheet", ] let documentPicker = UIDocumentPickerViewController(documentTypes: Utils.docsTypes, in: .import) documentPicker.delegate = self documentPicker.allowsMultipleSelection = true present(documentPicker, animated: true, completion: nil)
    

3
投票
我遇到的困难是如何为 PickerView 指定一些特定格式,例如 .pptx 和 .xlsx 文件。下面是一些代码,用于创建具有一些常用类型的 PickerView...

let types: [String] = [ kUTTypeJPEG as String, kUTTypePNG as String, "com.microsoft.word.doc", "org.openxmlformats.wordprocessingml.document", kUTTypeRTF as String, "com.microsoft.powerpoint.​ppt", "org.openxmlformats.presentationml.presentation", kUTTypePlainText as String, "com.microsoft.excel.xls", "org.openxmlformats.spreadsheetml.sheet", kUTTypePDF as String, kUTTypeMP3 as String ] let documentPicker = UIDocumentPickerViewController(documentTypes: types, in: .import) documentPicker.delegate = self documentPicker.modalPresentationStyle = .formSheet self.present(documentPicker, animated: true, completion: nil)

我发现有两个地方对于整理此列表很有用:

https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html

https://escapetech.eu/manuals/qdrop/uti.html

希望对某人有帮助!


2
投票
这是 UIDocumentPickerViewController 的 SwiftUI 版本。

感谢这篇博文:

https://capps.tech/blog/read-files-with-documentpicker-in-swiftui

我只是在这里发布代码,以防博客文章消失,因此它被保留。

(我稍微调整了代码以复制所选的证书文件并将数据写入Library文件夹;在博客中,它复制文本文件的内容。)

import SwiftUI struct ContentView: View { @State var fileContent:Data = Data() @State var showDocumentPicker = false var body: some View { Button() { showDocumentPicker = true } label: { Text("click me to show file browser") } .sheet(isPresented: self.$showDocumentPicker) { DocumentPicker(fileContent: $fileContent) } } } struct DocumentPicker: UIViewControllerRepresentable { @Binding var fileContent: Data func makeCoordinator() -> DocumentPickerCoordinator { return DocumentPickerCoordinator(fileContent: $fileContent) } func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPicker>) -> UIDocumentPickerViewController { //The file types like ".pkcs12" are listed here: //https://developer.apple.com/documentation/uniformtypeidentifiers/system_declared_uniform_type_identifiers?changes=latest_minor let controller: UIDocumentPickerViewController = UIDocumentPickerViewController(forOpeningContentTypes: [.pkcs12], asCopy: true) controller.delegate = context.coordinator return controller } func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext<DocumentPicker>) { print("update") } } //struct class DocumentPickerCoordinator: NSObject, UIDocumentPickerDelegate, UINavigationControllerDelegate { @Binding var fileContent: Data init(fileContent: Binding<Data>) { _fileContent = fileContent } func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { let fileURL = urls[0] let certData = try! Data(contentsOf: fileURL) if let documentsPathURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first { let certURL = documentsPathURL.appendingPathComponent("certFile.pfx") try? certData.write(to: certURL) } } }
    

1
投票
这将帮助您实现下载/上传功能

UIDocumentMenuViewController *importMenu = [[UIDocumentMenuViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeImport | UIDocumentPickerModeExportToService];

欲了解更多信息,请阅读

Apple 文档


1
投票
iCloud 访问所有类型的文件#

func openiCloudDocuments(){ let importMenu = UIDocumentPickerViewController(documentTypes: [String("public.data")], in: .import) importMenu.delegate = self importMenu.modalPresentationStyle = .formSheet self.present(importMenu, animated: true, completion: nil) }
    

-1
投票
您可以使用

NSURLSession

 来实现您所描述的内容。

您必须将显示的目标目录限制为应用程序的文档目录。应用程序没有对文件系统的完全访问权限。

© www.soinside.com 2019 - 2024. All rights reserved.