SwiftUI:在用户使用 DocumentPicker 选择文件后显示数组中的文件 url

SwiftUI: Display file url from Array after user Picks file using DocumentPicker

我遵循了有关从用户选择的文档中获取 Url 并能够将其显示在视图上的教程。我现在的问题是我想将那些 Url 添加到数组中。然后从数组中获取项目并将它们打印到视图上。它的工作方式是用户按下一个按钮,sheet 随文件应用程序弹出。用户可以在那里选择文档。用户选择文档后,Url 将打印在视图上。要打印 Url 是使用此

    //if documentUrl has an Url show it on the view
    If let url= documentUrl{
             Text(url.absoluteString)
   }

问题是当我做同样的事情时

   If let url= documentUrl 

在 Url 甚至添加到数组之前 运行 并且应用程序崩溃

这是完整的代码

    //Add the Urls to the array
    class Article: ObservableObject{
        var myArray:[String] = []

    }

    struct ContentView: View {
        @State private var showDocumentPicker = false
        @State private var documentUrl:URL?
        @State var myString:URL?
        @ObservedObject var userData:Article

        // Func for onDismiss from the Sheet
         func upload() {
             // add the Url to the Array
            DispatchQueue.main.async{
                userData.myArray.append(documentUrl!.absoluteString)
            }
        }

var body: some View {
    VStack{
        //If have Url reflect that on the View
        if let url = documentUrl{
            //Works
            Text(url.absoluteString)
            //doesntwork
            Text(userData.myArray[0])
        }
        
        }
        Button(action:{showDocumentPicker.toggle()},
                        label: {
                     Text("Select your file")
                 })
            .sheet(isPresented: $showDocumentPicker, onDismiss: upload )
        {
                DocumentPicker(url: $documentUrl)
                    }
    }
}

我想做的主要事情是在用户选择文档后或 sheet 消失后将 ulrs 显示到视图中。因此,如果用户选择 1 Url,则只打印一个。如果之后选择另一个,则显示 2 个,依此类推。 这是用于选择文档的documentPicker代码

            struct DocumentPicker : UIViewControllerRepresentable{
        @Binding var url : URL?


func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
    
    //initialize a UI Document Picker
    let viewController = UIDocumentPickerViewController(forOpeningContentTypes: [.epub])
    viewController.delegate = context.coordinator
    print("1")
    return viewController
}

func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {
    print("Swift just updated ")
    print("2")
}

    }


    extension DocumentPicker{
        func makeCoordinator() -> Coordinator {
            Coordinator(self)
        }

class Coordinator:NSObject, UIDocumentPickerDelegate{
    let parent: DocumentPicker
    init(_ documentPicker: DocumentPicker){
        self.parent = documentPicker
    }
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        guard let url = urls.first else{return}
        parent.url = url
        print("3")
    }

}
}

不确定我是否没有以正确的方式处理这个问题?我查看了不同的教程,但找不到任何内容。

可观察对象没有更改触发器。要通知可观察对象已更改,请使用以下示例之一:

class Article: ObservableObject {
    @Published var myArray:[String] = []
}

class Article: ObservableObject {
    private(set) var myArray:[String] = [] {
        willSet {
            objectWillChange.send()
        }
    }

    func addUrl(url: String) {
        myArray.append(url)
    }
}

官方文档:https://developer.apple.com/documentation/combine/observableobject

使用.fileImporter presentation modifire (above ios 14)

.fileImporter(isPresented: $showDocumentPicker,
                      allowedContentTypes: [.image],
                      allowsMultipleSelection: true)
        { result in
            // processing results Result<[URL], Error>
        }