iosxcodeprovisioning-profileentitlementsapple-developer

Adding Entitlements to Provisioning Profile


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)")
                }
            }
        } ````

Solution

  • 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.