Xcode 15's "Replace Container" feature replaces the container with incorrect permissions?

I recently updated to Xcode 15.0 and seem to be encountering permissions related errors after using the Replace Container function to replace an app container. Similarly, editing the current run scheme and choosing a new App Data container fails with an identical error.

It seems like the Documents directory and other similar directories are blocked from being able to write. Here is an example of what appears in the log after replacing the container:

Failed to create directory /var/mobile/Containers/Data/Application/A3C32E7A-34F3-4C69-B037-478027F2A4AC/Library/Preferences because of 13.
Couldn't write values for keys (
    "/google/measurement/app_instance_id"
) in CFPrefsPlistSource<0x280a82760> (Domain: com.google.gmp.measurement, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No): Directory needed
os_unix.c:47395: (13) lstat(/private/var/mobile/Containers/Data/Application/A3C32E7A-34F3-4C69-B037-478027F2A4AC/Documents)
- Permission denied os_unix.c:47395: (13) lstat(/private/var/mobile/Containers/Data/Application/A3C32E7A-34F3-4C69-B037-478027F2A4AC/Documents/<redacted>.sqlite)
- Permission denied os_unix.c:46898: (13) statfs(/private/var/mobile/Containers/Data/Application/A3C32E7A-34F3-4C69-B037-478027F2A4AC/Documents/<redacted>.sqlite)
- Permission denied

Steps to reproduce:

  1. Create a new app and replace -viewDidLoad: with the following. This will write a string to a new file and read that string:
NSFileManager * const fileManager = [NSFileManager defaultManager];
NSURL * const documentsDirectoryURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
if (!documentsDirectoryURL) {
    [NSException raise:@"DocumentsDirectoryException" format:@"Application documents directory URL is nil"];
}
NSURL * const fileURL = [documentsDirectoryURL URLByAppendingPathComponent:@"test.txt"];
if ([fileManager fileExistsAtPath:[fileURL path]]) {
    NSError *error;
    if (![[NSFileManager defaultManager] removeItemAtPath:[fileURL path] error:&error]) {
        [NSException raise:@"DocumentsDirectoryException" format:@"Encountered error removing file: %@",error];
    }
}

NSString * const fileContents = [NSString stringWithFormat:@"Date: %@",[NSDate date]];
NSError *error;
if (![[fileContents dataUsingEncoding:NSUTF8StringEncoding] writeToURL:fileURL options:0 error:&error]) {
    [NSException raise:@"DocumentsDirectoryException" format:@"Encountered error writing to file: %@",error];
}

NSString * const writtenFileContents = [[NSString alloc] initWithData:[NSData dataWithContentsOfURL:fileURL] encoding:NSUTF8StringEncoding];
NSLog(@"Written file contents: %@", writtenFileContents);
  1. Run the app and observe the log message "Written file contents: ..."
  2. Save the app container via Window > Devices & Simulators by clicking the app, clicking the "(...)" button, and then clicking "Download Container..."
  3. Use the same procedure in step 3 but instead, click "Replace Container..." and choose the existing app container that was downloaded
  4. Run the app again and observe that it fails with the following exception message:
*** Terminating app due to uncaught exception 'DocumentsDirectoryException', reason: 'Encountered error writing to file: Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file “test.txt” in the folder “Documents”." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/CF1E09C8-7BE2-4D87-8AD2-648AFBE038A5/Documents/test.txt, NSUnderlyingError=0x2831d4d50 {Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"}}'

Is anyone else encountering this issue and can confirm? Are my next steps to create a bug report? Is there a manner to escalating the bug report? This is a pretty core piece of functionality for QA and testing apps.

Post not yet marked as solved Up vote post of awojnowski Down vote post of awojnowski
5.4k views

Replies

The error still persists with latest Xcode 15.1 RC1 released today, here's the full error log

iOS 17.2 Beta (21C5054b)


Error transfering container '/Users/........ 2023-12-05 15:57.22.047.xcappdata'
Domain: DVTDeviceErrorDomain
Code: 7
User Info: {
    DVTErrorCreationDateKey = "2023-12-05 19:46:17 +0000";
}
--
The specified file could not be transferred.
Domain: com.apple.dt.CoreDeviceError
Code: 7000
User Info: {
    NSURL = "file:///Users/........ 2023-12-05 15:57.22.047.xcappdata/AppData/";
}
--
The provided file path could not be opened: No such file or directory
Domain: com.apple.dt.remoteservices.error
Code: 11007
--


System Information

macOS Version 14.1.2 (Build 23B92)
Xcode 15.1 (22502) (Build 15C65)
Timestamp: 2023-12-05T16:46:17-03:00

This bug still exists in release candidate Xcode15.1! Also, there is no feedback whether the container is loaded on the iPad (this was well shown in Xcode 14). Please fix this issue. We cannot develop and test our apps anymore.

Confirming this remains to be an issue with Xcode 15.1 and iOS 17.2 using the instructions in this thread.

Confirming this remains to be an issue with Xcode 15.1 and iOS 17.2 using the instructions in this thread.

Yep. I just tried this for myself and I still see the problem. I added my own comments to the bug (FB13253099) and asked that the Xcode folks look at this again.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I'm also seeing this. This has been a useful data recovery strategy for us in some support cases, so this capability being out of action is pretty frustrating!

I'm glad I found this thread, I've been able to dig out an older iPad and restore an application container there to proceed.

This bug still exists in Xcode15.2!!! It's so frustrating, we lost 2 months of testing and development is delayed. This future is so important for apps using database also it is the best way to make backups. Please fix it.

Same problem. In my case, there was 'Application Support' folder at first. When my application reached any page which imported WebKit framework, the 'Application Support' folder has been missing.

My system configuration for development

  • Xcode 15.2
  • iOS 17.2.1
  • Mac 14.2.1

For what it's worth.

On Thursday I finished revisions on an app I’m building. On Friday I downloaded the container for storage and backup. Then I upgraded my Mac, iPad, and xCode to support the latest versions of each. I made a few adjustments to the container and did the Replace Container process. Which has always worked before. OOPs.

I currently have: MacOS Sonoma: 14.2.1 xCode: 15.2 (15C500b) iPadOS: 17.3

My Development App is a sketch based app where each new sketch is stored to the database as a folder location in the documents folder Documents/pm_data/sketchName/ (sketchName like “dpc_ch1_pg1L” with L for landscape orientation). Inside the sketchName folder may be series of various images (representing sketch layers) plus a pList that describes the sketch construction. The Development App currently has 107 sketch page folders in the Documents/pm_data/ directory.

This is the process I used…to discover the error…

Download Container: • Saves the container including AppData/Documents with the sqlite3 database showing permissions of 777. Currently the container has 107 sketch pages. This is used for back storage and retrieval. I made a couple of adjustments to this container.

Replace Container: • Reinstalls everything from the previously downloaded container, including AppData/Documents/pm_data with 107 sketch pages. plus the sqlite3 database. • However, no connection to the reinstalled database works. • If I download this reinstalled container, the sqlite3 database still shows permissions of 777, and all the sketch data folder as well.

Development App Vanilla Install via Run in xCode • Create a new sketch view • Make a simple sketch • Save sketch location to sqlite3 works • Reopen sketch from the table cell in the app’s “open document” window works great

Questions: • Why does the vanilla database which is copied from the app bundle (on first install) to the Documents folder work? • Why does the Replace Container database in the Documents folder not work?

This is the function my code uses to copy the database from the bundle to Documents. Notice all the print() lines which are turned on for debugging.

/* This function is in PM_DB.swift and called from AppDelegate.swift PM_DB.sharedInstance().databaseURL() */ func databaseURL() { let fileManager = FileManager.default let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)

    // If array of paths is empty, the document folder was not found.
    guard urls.count != 0 else {
        print("Can't find document url.")
        return
    }
    
    let finalDatabaseURL:URL = urls.first!.appendingPathComponent("mats.sqlite3")
    print(finalDatabaseURL)
    do {
        // Check if the db already exists in directory.
        _ = try finalDatabaseURL.checkResourceIsReachable()
        print("The db mats.sqlite3 exists in the document directory.")
    } catch {
        if let bundleURL = Bundle.main.url(forResource: "mats", withExtension: "sqlite3") {
            print("The db mats.sqlite3 exists in the bundle directory.")
            do {
                try fileManager.copyItem(at: bundleURL, to: finalDatabaseURL)
                print("The db mats.sqlite3 was copied to the document directory.")
            } catch _ as NSError { // Handle the error
                print("DB copy failed! Error:\(error.localizedDescription)")
            }
        } else {
            print("The db does not exist in bundle folder")
        }
    }
}

My analysis:

  1. Delete App and doing a Vanilla Install, xCode gives this log display:

file:///var/mobile/Containers/Data/Application/9DB4C836-B335-46B6-94C1-DEB5AFD1C3F2/Documents/mats.sqlite3 The db mats.sqlite3 exists in the bundle directory. The db mats.sqlite3 was copied to the document directory.

WebContent process (0x113018680) took 1.463351 seconds to launch

  1. Then I closed the running Vanilla App after the database is copied to the document directory > and in xCode Start Active Scheme to run the app, this gives an xCode log display:

file:///var/mobile/Containers/Data/Application/B33A2183-61AB-4F84-870B-19B7F1036B07/Documents/mats.sqlite3 The db mats.sqlite3 exists in the document directory.

WebContent process (0x110018680) took 1.450069 seconds to launch In this case, I am able to create a new sketch, save it and reopen it. The newly installed database in the document directory works!

  1. Then I stop running Vanilla App above > and Replace Container with original Download Container> and in xCode Start Active Scheme gives this xCode log display:

file:///var/mobile/Containers/Data/Application/3F07E227-81EA-4C0D-BE7E-A694A0B159A7/Documents/mats.sqlite3 The db mats.sqlite3 exists in the bundle directory. DB copy failed! Error:The file “mats.sqlite3” couldn’t be opened because you don’t have permission to view it.

Could not create a sandbox extension for temporary file '/private/var/mobile/Containers/Data/Application/3F07E227-81EA-4C0D-BE7E-A694A0B159A7/tmp/' Failed to get cache main folder: path for application cache was not found (errno = 13, count = 1, len = 99, path = /private/var/mobile/Containers/Data/Application/3F07E227-81EA-4C0D-BE7E-A694A0B159A7/Library/Caches) WebContent process (0x113018680) took 1.340805 seconds to launch

So question: Why is iPadOS: 17.3 not recognizing the Replace Container mats.sqlite3. It should print("The db mats.sqlite3 exists in the document directory.") and skip the rest of the function.

Apple your system is failing on this: // Check if the db already exists in directory. compared to when working as it should in number 2 above.

So, to double check, I downloaded this latest Replacement Container and the database checks out using the terminal; all the info is there; so, the Replacement Container gets loaded correctly. My debug code confirms Apple isn’t seeing the Replaced database. In my case, the database is simple, only one table. As a workaround I’m thinking of stripping the database out of the Downloaded Container, using Replace Container to add it back to the app, and then rebuilding the copied database from the Bundle, one time in code, to repair access to the current 107 sketch pages. This is a kludge at best, and should work as long as the sketch data isn’t hosed as well.

For what it's worth continued.

As a workaround I’m thinking of stripping the database out of the Downloaded Container, using Replace Container to add it back to the app, and then rebuilding the copied database from the Bundle, one time in code, to repair access to the current 107 sketch pages. This is a kludge at best, and should work as long as the sketch data isn’t hosed as well.

This did not work. Here is the result:

file:///var/mobile/Containers/Data/Application/13A2480E-8E0F-4D7B-A95A-25AD8C5BD16D/Documents/mats.sqlite3

The db mats.sqlite3 exists in the bundle directory.

DB copy failed! Error:The file “mats.sqlite3” couldn’t be opened because you don’t have permission to view it.

Could not create a sandbox extension for temporary file '/private/var/mobile/Containers/Data/Application/13A2480E-8E0F-4D7B-A95A-25AD8C5BD16D/tmp/' Failed to get cache main folder: path for application cache was not found (errno = 13, count = 1, len = 99, path = /private/var/mobile/Containers/Data/Application/13A2480E-8E0F-4D7B-A95A-25AD8C5BD16D/Library/Caches) WebContent process (0x10f018680) took 1.509142 seconds to launch

So, The Replace Container was stripped of the database before replacement. Then added back to the iPad app. And the bundle database can be seen existing, but now cannot be copied to the documents directory.

I need the pieces-parts and database in the documents folder because I may need to edit and save things during development. Using Replacement Container is off the list of recovery options for me until it can be fixed by Apple. I have another idea using only the bundle, but it will take a bit more time to test. At least I now have working code to rebuild the database.

I had exactly the same problem. Replaces container on my device and then app was not usable anymore with this container. It was throwing me the error that CoreData sqlite file cannot be written anymore. Updated everything to the latest release - Xcode 15.3, iOS 17.4 ... doesn't help

After a lot of investigating I have found a little workaround for me: I gave the affected files some more permissions.

I navigated with the terminal into the app data package into the specific directory which is throwing me the errors (for me it was the CoreData files) then I give for this files some more permissions:

Example from me:

cd AppData/Library/Application\ Support
chmod 0777 *

Tried to replace the container again. And now it's working fine for me. I hope it can help someone ...

  • I have tried this with Xcode 15.3, Sonoma 14.4 and iOS 17.4, and still having the file permission denied. The file is under AppData/Documents. Did I miss any extra step?

    I even tried without making changes to the container, just downloading and then replacing it right away, it still shows the error.

Add a Comment

Same problem, except I only need to Download Container which doesn't work with Xcode 15.3 on MacOS Sonoma 14.2.1 using an iPhone 14 Pro. Or to be precise - it works, but the Container contains only very little data :-/

Since the problem seems to be related to the updated debugging system I installed the latest Xcode 14.3.1 from xcodereleases.com. That done I had to change the CFBundleVersion in the Info.plist + Version.plist to 22265, as mentioned here: https://stackoverflow.com/questions/76958016/is-there-a-way-to-run-xcode-14-on-macos-sonoma

Now I can run Xcode 14.2.1 and Download a full container :-)

It might work for Replacement also?

Cheers Thomas Rued

Just writing in to add I'm still seeing this on with Xcode 15.3 (15E204a) and iOS 17.5.

Thomas Rued above seems to be correct -- this looks like a permissions/ownership issue in when the container is replaced, and making everything world writable 'fixes' the issue. (But then of course, permissions in the replaced container are then different than if the container hadn't been replaced).