I'm building an iOS app that needs to access the device's Documents and Downloads folder occasionally. To do this, I use the 'startAccessiningSecurityScopedResource()' method. I had to enable the 'App Sandbox' entitlement in Xcode for this to work. After doing this, the app works perfectly in the iOS simulator, but it can no longer be installed to my physical test iPad. I've created the Provisioning Profiles in the Dev Portal, but when I try to add them under Devices and Simulators, it says failed to install one or more profiles to the device. I can force it to still by turning OFF automatically manage signing, but then it either tells me the entitlements for app sandbox and document read/write aren't found (these will NOT appear when creating a provisioning profile) OR, it let's me build, but then I get a popup saying can't install, and in the debug it says that a valid provisioning profile for this executable was not found. Anyone have any idea what's going on?
I've tried removing all provisioning profiles from the developer console, and from the computer / iPad and reinstalling them.
Edit: Here's my UIDocumentPicker code:
didPickDocumentsAt urls: [URL])
{
let fileManager = FileManager.default
let songsFolderURL = fileManager.documentDirectory().appendingPathComponent("Songs", isDirectory: true)
// Start accessing secured resources
guard songsFolderURL.startAccessingSecurityScopedResource() else {
print("Song Folder Access Issue")
return}
// If Songs folder doesn't exist in the app's documents, try to create it
if !fileManager.fileExists(atPath: songsFolderURL.path)
{
do
{
try fileManager.createDirectory(at: songsFolderURL, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Error creating song folder: \(error)")
}
}
// Stop accessing secured resources
defer {songsFolderURL.stopAccessingSecurityScopedResource() }
// For each selected song...
for song in urls {
do {
// Access secured resource
guard song.startAccessingSecurityScopedResource() else {
print("Song Access Issue")
return}
// Copy song from source location to app's documents/songs folder
try fileManager.copyItem(at: song, to: songsFolderURL.appendingPathComponent(song.lastPathComponent))
// Create CoreData song object to be saved to core data
let _song = Songs(context: PersistenceController.shared.container.viewContext)
_song.name = song.lastPathComponent
// Stop accessed secured resources
defer {song.stopAccessingSecurityScopedResource() }
// Save song data to coredata
PersistenceController.shared.save()
} catch {
print("Error copying file: \(error)")
}
}
} ````
You don't need a sandbox entitlement on iOS. That is only for macOS apps.
You don't need to use startAccessingSecurityScopedResource
for your app's own documents folder - It is inside your app's sandbox.
Also, the way you are obtaining the URL for this folder isn't correct for iOS. You should use something like
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
You do need to use startAccessingSecurityScopedResource
for the url's that are passed to your delegate method - These are URLs for the files outside of your sandbox that the user has selected.