-1

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)")
                }
            }
        } ````
Ray S.
  • 3
  • 2
  • 1
    The "App Sandbox" stuff is for macOS apps, not iOS apps. – HangarRash Mar 14 '23 at 00:20
  • If I don't enable it in the entitlements, my iOS app does not have permission to access the Documents and Downloads folder. Is there another way to do this? – Ray S. Mar 14 '23 at 00:49
  • An app can't access files and folders directly. You need to use a `UIDocumentPickerViewController` – Paulw11 Mar 14 '23 at 03:36
  • @Paulw11 - I am using a UIDocumentPickerViewController – Ray S. Mar 14 '23 at 05:02
  • Then you should [edit] your question to show the relevant code; How do you obtain the bookmark and how do you use it later on. You don't need any entitlements to use UIDocumentPickerViewController. – Paulw11 Mar 14 '23 at 06:27
  • @Paulw11 I edited my question as you suggested. If I remove the App Sandbox entitlement then, then the app builds on my iPad, however it error at the first startAccessingSecurityScopedResource. When in Sandbox mode, it won't build on my iPad, but works perfectly in the simulator. – Ray S. Mar 14 '23 at 18:30
  • "I use the 'startAccessiningSecurityScopedResource()' method. I had to enable the 'App Sandbox' entitlement in Xcode for this to work" ... "When in Sandbox mode, it won't build on my iPad, but works perfectly in the simulator" Wait, what? There is no "Sandbox mode" on iPad; you are _always_ sandboxed in an iOS app. It sounds like you are describing a _Mac_ app. I think you've created your project incorrectly. – matt Mar 14 '23 at 18:37
  • @matt Is there a way I can tell if the project was created incorrectly? I'm pretty sure when I created it I selected iOS and then App. – Ray S. Mar 14 '23 at 18:42
  • You shouldn't be able to add a sandbox entitlement at all. There is no such entitlement for iOS. If it runs without the entitlement, what error do you get? Please make an effort to provide information! We shouldn't have to prompt you for code, error details, etc. – matt Mar 14 '23 at 19:31
  • I add the entitlement via the entitlements file and also turn on app sandbox in the build settings. I gave the error above: 'however it error at the first startAccessingSecurityScopedResource. ' Without app sandbox, the else executes. If I print the actual error it says I don't have permission to read the file. – Ray S. Mar 14 '23 at 19:56
  • You don't need to `startAccessingSecurityScopedResources` for folders in your sandbox, but you don't have the right code to get your app's document directory - see https://www.hackingwithswift.com/example-code/system/how-to-find-the-users-documents-directory. URLs in your sandbox are not security scoped. The urls provided to the `didPick` delegate method are security scoped. – Paulw11 Mar 14 '23 at 20:58
  • @Paulw11 Thank you! I'll take a look at that example. I'm trying to access a folder outside the app in the devices Documents Directory, and then copy it to the app's document directory. Knowing now it's not a provision issue but it's a code issue is very helpful. – Ray S. Mar 14 '23 at 21:07
  • @Paulw11 The issue was indeed how I was getting the documents directory. Once I changed that, and kept startAccessingSecurityScopeResources for the URL of the devices documents, everything is now working! Please post that as the answer and I will accept it. – Ray S. Mar 14 '23 at 22:47

1 Answers1

0

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.

Paulw11
  • 108,386
  • 14
  • 159
  • 186