在 swift (iOS) 中实现文档选择器
Posted
技术标签:
【中文标题】在 swift (iOS) 中实现文档选择器【英文标题】:Implement Document Picker in swift (iOS) 【发布时间】:2016-05-18 10:30:11 【问题描述】:我想在我的 ios 应用程序中选择任何类型的文件(.pdf、.docs、.xlsx、.jpeg、.txt、.rtf 等)功能。点击上传按钮,我希望我的应用打开一个目录并选择文件(DocumentsPicker
)
@IBAction pickDocument(sender: UIButton)
//Open Document Picker
Swift
中的任何方法?
【问题讨论】:
iOS 应用是沙盒化的,因此您无法在应用沙盒之外打开任何目录。另外,您的问题是广泛的,并且没有显示您尝试自己解决此功能的任何尝试。 @Nilesh Pol:如果我必须从这里选择文件并将其上传到服务器怎么办。我必须下载它然后通过多部分发送还是有其他方法可以这样做?请提出建议。 @Ishika 文档选择器为你下载。你不需要自己做。 【参考方案1】:iOS 14 更新:您不需要任何功能。只需创建一个具有适当类型的UIDocumentPickerViewController
,实现委托,就完成了。
更多信息in this answer。来自那里的代码:
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)
你怎么称呼这一切?将以下代码添加到您的 click 函数中:
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") )
尽情享受吧。
【讨论】:
无法设置为 pdf 仅与“public.pdf”显示此错误“传入的类型 public.pdf 不符合 public.content 或 public.item。如果您要导出新类型,请确保它符合适当的父类型。” 为什么我找不到可用的位置 @Alexander 我们如何添加不使用默认色调且不超出可用图标大小范围的自定义图像? @Alexander 我可以让它适合的唯一方法是将我的图标的大小减小到 25 x 25 但它非常像素化 @Alexander 如果我必须从这里选择文件并将其上传到服务器怎么办。我必须下载它然后通过多部分发送还是有其他方法可以这样做?【参考方案2】:您可以使用UIDocumentPickerViewController
从“文件”应用或 iCloud Drive 中获取文件。
-
从
iCloud
功能激活Key-value storage
和iCloud Documents
:
在要打开文档选择器的视图控制器上导入以下框架:
import MobileCoreServices
// For iOS 14+
import UniformTypeIdentifiers
从UIDocumentPickerDelegate
实现以下方法:
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL])
// you get from the urls parameter the urls from the files selected
创建一个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
s 添加到types
NSArray
。要查看所有可用的类型,您可以查看UTType Docs
当文档选择器在 iOS 11 上打开并且您尝试在 Google Drive 中选择一个文件时,该文件可能由于错误而被禁用:http://www.openradar.me/24187873
【讨论】:
为什么我们需要来自 iCloud 的键值存储? @jomafer 你在这个答案中不需要它 @Hatim 那为什么在步骤 1 中提到它? “激活键值存储和 [...]”【参考方案3】: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 支持:
【讨论】:
您是指 iCloud 文档而不是键值存储吗? @Hatim 我没有启用iCloud Documents
,只有Key-Value storage
。这已经足够了,不需要任何额外的设置。【参考方案4】:
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)
【讨论】:
【参考方案5】: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)
【讨论】:
【参考方案6】:这将帮助您实现下载/上传功能
UIDocumentMenuViewController *importMenu = [[UIDocumentMenuViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeImport | UIDocumentPickerModeExportToService];
更多信息请阅读Apple Documentation
【讨论】:
【参考方案7】: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)
【讨论】:
如何使用它来访问:.o*** 文件?【参考方案8】:我纠结的是如何为 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
希望对某人有所帮助!
【讨论】:
【参考方案9】:您可以使用NSURLSession
实现您描述的内容。
您必须将显示的目标目录限制为应用的文档目录。应用程序没有文件系统的完全访问权限。
【讨论】:
以上是关于在 swift (iOS) 中实现文档选择器的主要内容,如果未能解决你的问题,请参考以下文章