Objective: A consumer selects a folder in Recordsdata app the place they might create information in that folder. That is an iOS app. This folder path is saved within the iOS app, utilizing this app consumer would create file programmatically and put it aside within the app.
Challenge: For some cause based mostly on the under implementation, I can create file solely onetime in that folder and any subsequent file creation results in “Didn’t entry safety scoped useful resource”. To go round this, I would like to pick the folder once more after which ship it. THis shouldn’t be the expertise a consumer ought to face. A consumer ought to choose the folder path solely as soon as and it’s saved in iOS app, consumer ought to care about extra about creating information in that folder.
Under is the code
class FolderManager: NSObject, UIDocumentPickerDelegate {
// Singleton occasion for shared entry
static let shared = FolderManager()
personal override init() {}
// Operate to current the doc picker for choosing a folder
func selectFolder(from viewController: UIViewController) {
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.folder], asCopy: false)
documentPicker.delegate = self
documentPicker.allowsMultipleSelection = false
viewController.current(documentPicker, animated: true, completion: nil)
}
// Delegate methodology referred to as when a folder is chosen
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let selectedFolderURL = urls.first else { return }
saveFolderURL(selectedFolderURL)
}
// Operate to save lots of the folder URL as bookmark knowledge
func saveFolderURL(_ url: URL) {
do {
let bookmarkData = attempt url.bookmarkData(choices: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil)
UserDefaults.customary.set(bookmarkData, forKey: "selectedFolderURL")
} catch {
print("Error saving folder URL: (error)")
}
}
func retrieveFolderURL() -> URL? {
guard let bookmarkData = UserDefaults.customary.knowledge(forKey: "selectedFolderURL") else { return nil }
var isStale = false
let folderURL = attempt? URL(resolvingBookmarkData: bookmarkData, choices: [], bookmarkDataIsStale: &isStale)
if isStale {
print("Bookmark knowledge is stale")
// Deal with stale bookmark knowledge
do {
let newBookmarkData = attempt folderURL?.bookmarkData(choices: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil)
UserDefaults.customary.set(newBookmarkData, forKey: "selectedFolderURL")
} catch {
print("Error updating stale bookmark knowledge: (error)")
}
}
return folderURL
}
// Operate to create and save a file within the chosen folder
func createFileInFolder(fileName: String, fileContents: String) {
guard let folderURL = retrieveFolderURL() else {
print("Didn't retrieve folder URL")
return
}
if !folderURL.startAccessingSecurityScopedResource() {
print("Didn't entry safety scoped useful resource")
return
}
defer {
folderURL.stopAccessingSecurityScopedResource()
print("stoppedAccessingSecurityScopedResource")
}
let fileURL = folderURL.appendingPathComponent(fileName)
do {
attempt fileContents.write(to: fileURL, atomically: true, encoding: .utf8)
print("File created efficiently at (fileURL.path)")
} catch {
print("Error creating file: (error)")
}
}
}
I already reviewed some stackoverflow snippets based mostly on that the code is already modified as per startAccessingSecurityScopedResource, stopAccessingSecurityScopedResource.
Any assist is extremely appreciated.