Kann ich die URL auf eine Weise bestehen, die nach dem Neustart des App weiterhin gültig ist? Ich habe sogar ihren Quellcode in GitHub gefunden, aber er wird mit Storyboards implementiert, die ich nicht kenne, und ich habe es nicht geschafft, herauszufinden, wie sie es tun, obwohl ich einige Stunden für die Untersuchung des Code
Code: Select all
struct ContentView: View {
enum Constants : String {
case folderURLKey = "folderURL"
}
@State private var isShowingDocumentPicker = false
@State private var selectedFolderURL: URL?
@State private var fileList: [String] = []
var body: some View {
VStack {
Button("Select Dropbox folder") {
isShowingDocumentPicker = true
}
.padding(.bottom, 20)
if let folderURL = selectedFolderURL {
Text("Selected folder:")
Text(folderURL.path)
.foregroundColor(.blue)
.padding(.bottom, 20)
Button("Create random file") {
createRandomFile()
}
ForEach(self.fileList, id: \.self) { fileName in
Text(fileName).font(.caption2)
}
}
}
.buttonStyle(.bordered)
.sheet(isPresented: $isShowingDocumentPicker) {
FolderPickerView { folderURL in
selectedFolderURL = folderURL
if let url = folderURL {
let urlData = try! url.bookmarkData()
UserDefaults.standard.setValue(urlData, forKey: Constants.folderURLKey.rawValue)
}
}
}
.onAppear() {
let urlData = UserDefaults.standard.data(forKey: Constants.folderURLKey.rawValue)
if let urlData = urlData {
var isStale: Bool = false
let folderURL = try! URL(resolvingBookmarkData: urlData, bookmarkDataIsStale: &isStale)
self.selectedFolderURL = folderURL
self.fileList = self.listFiles(folderURL: self.selectedFolderURL!)
}
}
}
func listFiles(folderURL: URL) -> [String] {
var list: [String] = []
do {
if folderURL.startAccessingSecurityScopedResource() {
let contents = try FileManager.default.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil)
for fileURL in contents {
list.append(fileURL.lastPathComponent)
}
folderURL.stopAccessingSecurityScopedResource()
}
else {
print("Call to startAccessingSecurityScopedResource failed!!!!!")
}
}
catch {
print("ERROR: \(error)")
}
return list
}
func createRandomFile() {
if selectedFolderURL!.startAccessingSecurityScopedResource() {
FileManager.default.createFile(atPath: selectedFolderURL!.appendingPathComponent("random_file_\(UUID().uuidString).txt").path, contents: Data("Hello, world!".utf8))
selectedFolderURL!.stopAccessingSecurityScopedResource()
self.fileList = self.listFiles(folderURL: self.selectedFolderURL!)
}
else {
print("Call to startAccessingSecurityScopedResource failed!!!!!")
}
}
}
struct FolderPickerView: UIViewControllerRepresentable {
var onFolderSelected: (URL?) -> Void
func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
let picker = UIDocumentPickerViewController(forOpeningContentTypes: [.folder])
picker.delegate = context.coordinator
picker.allowsMultipleSelection = false // Solo una carpeta
return picker
}
func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(onFolderSelected: onFolderSelected)
}
class Coordinator: NSObject, UIDocumentPickerDelegate {
var onFolderSelected: (URL?) -> Void
init(onFolderSelected: @escaping (URL?) -> Void) {
self.onFolderSelected = onFolderSelected
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
onFolderSelected(urls.first)
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
onFolderSelected(nil)
}
}
}