Estoy tratando de extraer la URL del documento que un usuario ha seleccionado en el cuadro de diálogo "Abrir" predeterminado de mi aplicación macOS basada en documentos. Entiendo, se pasa un fileWrapper al método init, pero ¿hay alguna forma de extraer la ruta/URL de dicho contenedor?
Gracias,
Lars
El panel abierto le proporciona la URL si alguien hace clic en el botón Abrir (Aceptar). NSOpenPanel tiene una propiedad urls que contiene las URL de los archivos seleccionados.
Los importadores de archivos de SwiftUI le brindan una URL si la apertura fue exitosa.
.fileImporter(isPresented: $isImporting, allowedContentTypes: [.png, .jpeg, .tiff], onCompletion: { result in switch result { case .success(let url): // Use the URL to do something with the file. case .failure(let error): print(error.localizedDescription) } })ACTUALIZAR
El panel de apertura de documentos de SwiftUI funciona de manera diferente al importador de archivos. Podría intentar trabajar con NSOpenPanel directamente. El siguiente artículo debería ayudar:
Guardar y abrir paneles en aplicaciones macOS basadas en SwiftUI
La única forma en que pude hacer que esto funcionara fue agregar un inicializador personalizado a la vista de contenido que vuelve a escribir la URL en el documento. Muy poco elegante, pero aquí estamos:
aplicación:
import SwiftUI @main struct FileOpenApp: App { var body: some Scene { DocumentGroup(newDocument: FileOpenDocument()) { file in ContentView(document: file.$document, fileURL: file.fileURL) } } }Documento:
struct FileOpenDocument: FileDocument { var text: String var originalFilePath: String var firstOpen: Bool init(text: String = "Hello, world!") { self.text = text self.firstOpen = true self.originalFilePath = "NewFile Path" } static var readableContentTypes: [UTType] { [.exampleText, .CSVtext, .plainText] } init(configuration: ReadConfiguration) throws { guard let data = configuration.file.regularFileContents, let string = String(data: data, encoding: .utf8) else { throw CocoaError(.fileReadCorruptFile) } text = string self.firstOpen = true self.originalFilePath = "ReadPath" } func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { let data = text.data(using: .utf8)! return .init(regularFileWithContents: data) } }Vista de contenido:
struct ContentView: View { @Binding var document: FileOpenDocument var documentURL: URL? init(document: Binding<FileOpenDocument>, fileURL: URL?){ self._document = document self.documentURL = fileURL if document.firstOpen.wrappedValue == true { if let path = self.documentURL?.path { self.document.originalFilePath = path document.firstOpen.wrappedValue = false } } } var body: some View { TextEditor(text: $document.text) Text("ContentView Path: \(self.documentURL?.path ?? "no Document Path")") Text("Document Path: " + document.originalFilePath) } }