openradar-mirror icon indicating copy to clipboard operation
openradar-mirror copied to clipboard

23336152: Xcode 7.1: Cannot use xcappdata package in simulator

Open openradar-mirror opened this issue 9 years ago • 10 comments

Description

This is a duplicate of rdar://20622011

Summary: Prior to Xcode 6, we could extract an xcappdata package from a device and use it in either a device or simulator to prepopulate data. This was useful for stress/scale testing, migration testing, or reproducing pathological cases. I described its use in a blog post here: http://corporationunknown.com/blog/2014/07/10/preloading-development-data-into-your-ios-app/

In Xcode 6, the ability to use the package on a simulator broke (possibly due to the simulator disk directory rearrangement?) and would repeatedly post an alert saying the data couldn't be loaded, but will on next launch of the app in the simulator. Unfortunately, relaunching would simply present the same alert, again and again.

Now in Xcode 6.3, it doesn't even seem to try. The xcappdata package is not installed in the simulator, and no alert is presented. It just silently fails.

Steps to Reproduce:

  1. Create a new project using the “Master-Detail Application” template that uses Core Data.
  2. Run the application on a device.
  3. Add 5 items.
  4. You may stop running the application on your device—the following steps aren’t affected by it running or not.
  5. Open the Xcode Organizer, select the “Applications” section of your device under the Devices tab.
  6. Select your test application. You should see a bunch of folders and files populate the “Data files in Sandbox”. (This may not populate right away, so be patient.)
  7. Click the “Download” button at the bottom and save the xcappdata package to your Desktop, giving it a descriptive name like 'v0 - 5 items.xcappdata'.
  8. Click “Delete” to remove the application from the device—we will try to start with a clean install for the next steps.
  9. Create a new Group in your project. I name mine “Test Data”.
  10. Add v0 - 5 items.xcappdata to the group.
  11. Select “Copy items into group folder”.
  12. Do not add it to any targets.
  13. Launch the app while holding the Option key—either Option-clicking the Run button, or Option-Command-R. A scheme configuration sheet will appear.
  14. In the Options tab, select v0 - 5 items.xcappdata from the Application Data menu and click “Run”.

Expected Results: The app would launch with 5 records pre-installed, based on the xcappdata package.

Actual Results: The app always launches fresh.

Version: Xcode 6.3 (6D570), OS X 10.10.3 (14D136)

Notes: A similar report is known to have been filed as rdar://20621826

Configuration:

Attachments: 'AppDataTest.zip' was successfully uploaded.

Product Version: Xcode 7.1 (7B91b) Created: 2015-10-30T18:40:45.020470 Originated: 2015-10-30T19:40:00 Open Radar Link: http://www.openradar.me/23336152

openradar-mirror avatar Oct 30 '15 19:10 openradar-mirror

I've just figured it out that, as a workaround at least for Xcode 9.2/iOS 11.2 simulator, you can set (HOME/CFFIXED_USER_HOME) (I'm not sure whether of those actually works) environment variables in launch arguments to a path to .xcappdata/AppData, like shown below (I used SRCROOT relative path just for illustration of possibilities - it works with any other kind of path like absolute ones and etc). Beware that the changes in the app data will be reflected right in that folder, so if you don't want that, it makes sense to point it to the copy.

2018-01-19 7 41 48

grigorye avatar Jan 19 '18 18:01 grigorye

@grigorye I can't get your fixes to work in Xcode 12.3 and they still haven't fixed this bug. Got any bright ideas?

1oo7 avatar Mar 26 '21 14:03 1oo7

@grigorye I can't get your fixes to work in Xcode 12.3 and they still haven't fixed this bug. Got any bright ideas?

@1oo7 No, sorry, I don't have a solution for this. At quick glance it indeed no longer works (those environment variable values get ignored) and the whole thing is not fixed either.

OTOH, I've just checked, and could get it working at least to some extent, by employing xcrun simctl install_app_data <simulator-id> <xcappdata>. At least I see the change in the app data and the app gets terminated as part of the process, as documented in the usage... But it requires the pre-installed app in the simulator and it is definitely not as handy as just using run action environment variables.

$ xcrun simctl install_app_data
Install an xcappdata package to a device, replacing the current contents of the container.
Usage: simctl install_app_data <device> <path to xcappdata package>
	 This will replace the current contents of the container. If the app is currently running it will be terminated before the container is replaced.

grigorye avatar Mar 26 '21 16:03 grigorye

It's really hard to believe they let this kind of bug exist for 5+ years. I'm going to open a DTS ticket about this... still have one left before it expires in a couple of weeks. Maybe I can get their attention on it. (Maybe they thought they fixed it or didn't realize it was broken? An old JIRA that got lost in JIRA limbo?)

1oo7 avatar Mar 26 '21 16:03 1oo7

Probably it's no longer a big deal from their perspective. I mean, nowadays, we can drag-drop .xcappdata right into Simulator - from what I can see, it does the thing, and it kind of covers the manual test cases. And if we're interested in automation, simctl might be a solution.

grigorye avatar Mar 26 '21 16:03 grigorye

Firstly, @grigorye , thanks for being so responsive about this!

Probably it's no longer a big deal from their perspective. I mean, nowadays, we can drag-drop .xcappdata right into Simulator - from what I can see, it does the thing, and it kind of covers the manual test cases. And if we're interested in automation, simctl might be a solution.

Thanks for the tips.

Hmm. Without going into too many details, I am trying to create a series of automated tests to run on our CI system. These tests will check that our app boots up normally from a variety of different .xcappdata states, maybe 20 or more. The tests need to run in parallel on different simulators on the same machine. Between builds the system deletes all the simulator containers from ~/Library/Developer/CoreSimulator/, to guarantee each build starts off with the exact same clean slate.

So while I'm not against using a workaround, drag-and-drop won't do for the use case I'm having to solve. If I'm testing locally for debug purposes, I'll just use a device anyway.

So that leaves the script option. The challenge would be, how to know which simulator GUID corresponds with which Test Plan's run, when they're executing in parallel?

I really feel like this should just work in Xcode using the available UI they have. I mean, why did Apple add a UI to associate an .xcappdata with a Test Plan in Xcode 11, if they knew it didn't work? I'd imagine Apple's Xcode team has close to 100% test coverage around Xcode's test-related features, since tests that malfunction aren't very useful.

So I'm going to file a ticket with Apple Developer Technical Support about this. I'm hoping there's just an esoteric build setting that must be set a particular way. After all, it's not like Apple could write tests to cover every possible combination of Xcode build settings... there's more combinations of Xcode build settings than molecules in the known universe.

I'll let you know if they share anything helpful. Thanks again for your quick replies!

1oo7 avatar Mar 26 '21 18:03 1oo7

Note: another workaround is suggested here by Daniel Farrelly: https://jellystyle.com/2018/01/preloading-app-data In this one he uses environment variables to trigger build scripts to actually embed the .xcappdata into the app itself, which then in turn, copies the files out of the .xcappdata and into the app's container directories (like Library etc.).

This seems pretty legit but I still hope Apple has a rational explanation for this. Will let you know. Thanks

1oo7 avatar Mar 26 '21 18:03 1oo7

So I have had problems with both of the above workarounds.

The problem with using xcrun simctl install_app_data

There seems to be no way to know which .xcappdata to use at build-time or test-time based on which .xctestplan is currently being run. I tried adding a pre-test script to perform xcrun simctl install_app_data however none of the environment variables that get set by the .xctestplan are visible at this point. And there is no env. var. that says which test plan will be used. Same goes for build scripts.

So how is our script supposed to know which test plan will get used, in order to determine which .xcappdata to use?

The solution needs to work for both CI scripts and local developers who do everything using Xcode.

There might be a solution using one scheme per .xcappdata, but that doesn't scale well. If we use a workaround, it should be easy to stop using it when Apple fixed this bug, without having to refactor all our tests.

The problem with copying the .xcappdata at runtime

The problem with that second solution is that, on the first run after you change to a different .xcappdata file, the com.mycompany.myapp.plist file (which gets used at test-time as the basis for the app's UserDefaults.standard) will be the previous one that existed when "command-U" was pressed to build for testing and run tests. So, the first test run after changing to a different .xctestplan and .xcappdata, always fails because for some unknown reason.

I feel like there ought to be some way to cause the running app to reload UserDefaults from disk, but all the methods that sound like they should be related to this are deprecated or don't work anymore (e.g. .sync()).

Thoughts?

Anyone have any thoughts or suggestions on this?

Please see my stackoverflow about how to know which test plan is active from a build-phase script or pre-test script: https://stackoverflow.com/questions/66863111/how-can-it-be-known-to-a-build-script-which-xctestplan-will-be-used-at-build-ti

gistya avatar Mar 30 '21 00:03 gistya

Submitted FB9127508. This is absurd.

imWildCat avatar Jun 04 '21 16:06 imWildCat

any news about this?

felipecastrosales avatar Sep 08 '23 13:09 felipecastrosales