Objective: A person selects a folder in Recordsdata app the place they’d create recordsdata in that folder. That is an iOS app. This folder path is saved within the iOS app, utilizing this app person would create file programmatically and put it aside within the app.
Situation: For some motive primarily based on the under implementation, I can create file solely onetime in that folder and any subsequent file creation results in “Did not entry safety scoped useful resource”. To go round this, I would like to pick the folder once more after which ship it. THis isn’t the expertise a person ought to face. A person ought to choose the folder path solely as soon as and it’s saved in iOS app, person ought to care about extra about creating recordsdata in that folder.
Under is the code
class FolderManager: NSObject, UIDocumentPickerDelegate {
// Singleton occasion for shared entry
static let shared = FolderManager()
personal override init() {}
// Perform 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 technique known as when a folder is chosen
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let selectedFolderURL = urls.first else { return }
saveFolderURL(selectedFolderURL)
}
// Perform to save lots of the folder URL as bookmark information
func saveFolderURL(_ url: URL) {
do {
let bookmarkData = strive 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.information(forKey: "selectedFolderURL") else { return nil }
var isStale = false
let folderURL = strive? URL(resolvingBookmarkData: bookmarkData, choices: [], bookmarkDataIsStale: &isStale)
if isStale {
print("Bookmark information is stale")
// Deal with stale bookmark information
do {
let newBookmarkData = strive folderURL?.bookmarkData(choices: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil)
UserDefaults.customary.set(newBookmarkData, forKey: "selectedFolderURL")
} catch {
print("Error updating stale bookmark information: (error)")
}
}
return folderURL
}
// Perform to create and save a file within the chosen folder
func createFileInFolder(fileName: String, fileContents: String) {
guard let folderURL = retrieveFolderURL() else {
print("Did not retrieve folder URL")
return
}
if !folderURL.startAccessingSecurityScopedResource() {
print("Did not entry safety scoped useful resource")
return
}
defer {
folderURL.stopAccessingSecurityScopedResource()
print("stoppedAccessingSecurityScopedResource")
}
let fileURL = folderURL.appendingPathComponent(fileName)
do {
strive 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 primarily based on that the code is already modified as per startAccessingSecurityScopedResource, stopAccessingSecurityScopedResource.
Any assist is very appreciated.