我希望在我的iOS应用程序中实现选择任何类型的文件(.pdf, .docs, .xlsx, .jpeg, .txt, .rtf等)功能。当点击上传按钮时,我希望我的应用程序能够打开一个目录并选择文件(DocumentsPicker
)。
@IBAction pickDocument(sender: UIButton) {
//Open Document Picker
}
有任何方法在Swift
中实现这个吗?
我希望在我的iOS应用程序中实现选择任何类型的文件(.pdf, .docs, .xlsx, .jpeg, .txt, .rtf等)功能。当点击上传按钮时,我希望我的应用程序能够打开一个目录并选择文件(DocumentsPicker
)。
@IBAction pickDocument(sender: UIButton) {
//Open Document Picker
}
有任何方法在Swift
中实现这个吗?
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)
}
根据您的项目能力,启用和键共享。
在您的类中导入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将记录在您的终端中。
根据您的需要操纵documentTypes。在我的应用程序中,仅允许用户使用PDF,所以请随意自行适应。
kUTTypePDF
kUTTypePNG
kUTTypeJPEG
...
如果您想自定义您自己的菜单栏,请添加以下代码并在处理程序内自定义您自己的功能。
importMenu.addOption(withTitle: "Create New Document", image: nil, order: .first, handler: { print("New Doc Requested") })
享受它。
您可以使用UIDocumentPickerViewController
从文件应用程序或iCloud Drive获取文件。
iCloud
功能下的键值存储
和iCloud文档
:Import the following framework on the view controller you want to open the document picker:
import MobileCoreServices
// For iOS 14+
import UniformTypeIdentifiers
Implement the following method from UIDocumentPickerDelegate
:
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
// you get from the urls parameter the urls from the files selected
}
Create an UIDocumentPickerViewController
to display the File picker or 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)
types
NSArray
中添加更多UTType
。要查看所有可用类型,您可以检查UTType文档。UIDocumentMenuViewController
自 iOS 11 起已被弃用。我还发现当从模态视图控制器中呈现时,它很容易出现故障。
以下是直接使用选择器的方法:
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文档
,只启用了键值存储
。这已经足够了,不需要任何额外的设置。 - SoftDesignerUIDocumentPickerViewController(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)
}
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)
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)
}
}
}
我曾经遇到的问题是如何为 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)
在编制此列表时,我发现有两个地方非常有用:
希望能对某些人有所帮助!func openiCloudDocuments(){
let importMenu = UIDocumentPickerViewController(documentTypes: [String("public.data")], in: .import)
importMenu.delegate = self
importMenu.modalPresentationStyle = .formSheet
self.present(importMenu, animated: true, completion: nil)
}
UIDocumentMenuViewController *importMenu = [[UIDocumentMenuViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeImport | UIDocumentPickerModeExportToService];
了解更多,请阅读苹果文档
您可以使用NSURLSession
来实现您所描述的内容。
您需要将目标目录限制为您的应用程序文档目录。应用程序无法完全访问文件系统。