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.

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

This appears to be fixed in Version 16.0 beta (16A5171c). Tested with a device running iOS 17.5.1 and using the instructions in my original post.

I saw in the release notes for Xcode 15.4 that something like this has been addressed - (116698465) (FB13253099)

At least in my use case the problem seems to have been resolved. I am using SwiftData for managing persistence.

Use Case

  • download a container.
  • Manipulate the SQLite database
  • Replace the container.

The changes that I have made are visible in the app. This previously failed

Xcode - 15.4 MacOS - Sonoma 14.5 iOS - 17.5.1

I saw in the release notes for Xcode 15.4 that something like this has been addressed (116698465)

Right. I’ve recently learnt more about this issue, and the above fix is part of the solution. If for any given app you only ever used Xcode 15.4, you won’t see an issue. If, however, you used Xcode 15 through 15.3 to replace your app’s container, you may still run into problems (FB13800727).

See also this thread.

Share and Enjoy

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

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