An annoying thing that was introduced a few releases ago in the iOS Simulator is that your apps’ bundle and container directories change their names (a random UUID) every time you run them in Xcode. It makes it very annoying to test your app if you need to check the output files regularly or restore the app’s container to a known state before launching. I’ve found a relatively painless workaround though!
An experiment showed that the directory with the app’s container data is just renamed every time, which means its inode number is still the same. Briefly: every file (or rather a blob of data) on a UNIX-like filesystem (such as ext4 or HFS+) is identified by its inode number, and names in FS directories just point to those numbers. Typically, an inode (file) has one name, and it’s possible to create hard links to files, meaning there will be multiple names pointing to the same file (blob of data). That’s exactly what we need — one regular name that keeps changing and one constant name.
Reading https://stackoverflow.com/questions/1432540/creating-directory-hard-links-in-macos-x, we find out that hard links to directories are usually disabled (because they may lead to infinite cycles), and on OSX you can’t even use the
ln command for that. Hopefully, we still can use a system call, wrapped in the tiny program hardlink-osx, installed with:
Now, to practice.
First, find out your iOS simulator’s UUID with either
instruments -s devices or
xcrun simctl list devices. Let’s say it’s
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee, so now
cd ~/Library/Developer/CoreSimulator/Devices/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/data/Containers/Data/Application/ — that’s where all apps’ data is located on the simulator.
Now, how to find the one for your app? If it writes to
NSUserDefaults, there exists a file named
bundle_id is your app’s bundle ID), so you can do this (NB: the
** syntax is
zsh’s globbing syntax for matching all directories recursively; if you use
bash, you’ll need to employ
1 2 3
The main step here is creating the hard link. NB: you can’t create a hard link to a directory in the same parent directory, which means you need to create another root for links and then link, e.g.:
That’s it! Now you can use
../links/myapp to list files and other mischiefs (
NB: when you’ve reinstalled your app, you’ll need to manually remove the old directory and recreate the link:
1 2 3
Enjoy! Of course, it’s possible to come up with a script to link all your apps and make sure they’re always current, etc. If you have one, be sure to post it in the comments below.
A small tip: I sometimes need to test an app launching it from a known state (for example, logged in). To make a snapshot of the app’s data, I use the great tool
rsync to copy the whole hierarchy somewhere else, which is super easy now (NB: make sure you type in the trailing slashes in the following commands):
And to restore, I sync a saved snapshot back: