Scripting – iOS App Directory

One of the most common problems I run into during typical iOS development is needing to get access to my app’s directory. Unfortunately, apple has made this as difficult as they could by making it so that

  1. Each simulator has a non-deterministic directory
  2. Each application on that simulator has a non-deterministic directory
  3. Each time you install the app, it will get a new non-deterministic directory

Depending on the app you’re developing, you may be uninstalling and reinstalling multiple times a day, which means your app’s directory is going to change frequently. If you’re having to reset the simulators frequently, then it might be even worse.

The typical way people find their app directory is by throwing something like this into the app

However, this can be terribly inconvenient. I work in an environment where we don’t have this block of code as part of our git repo. I can toss this in, but I have to remember not to commit it. And finally, I usually don’t realize that I want this until after I have already built (we have an extremely slow build).

Luckily, there are some command line tools that can be chained together to solve these problems.

The goal of this script is to allow you to pick from a list of devices to open up an application directory for one of the apps installed on that simulator.

Note: I found out later that you can just add a --json to the commands, and then you can have the output be in json, and then you could use a json deserialization library instead of writing all of the custom parsing. I will probably wait to rewrite this until it stops working. No sense in changing something just for the sake of change.


The steps we’re going to take in the script are

  1. Find a list of simulators and which apps are installed on each simulator
  2. filter out simulators that we don’t care about
  3. make a list of the bundle identifiers of each app installed on the simulators
  4. filter out simulators that don’t have any apps installed on them
  5. prompt for which simulator
  6. prompt for which bundle identifier
  7. open a finder window

As a reference, this class structure is one I used to keep data consistent

 

 

Getting the list of simulators is simple. its just an xcrun command and some parsing (as mentioned, this could have been done easier but i didn’t know about the json flag)

I also put in some code to filter out devices based on key word matching (ie, iPhone, Air, etc) But the overwhelming majority of that code is just for parsing

I use it, and filter out devices that I’m not interested in like this

In my case, I don’t care about any watchOS devices because we aren’t doing apple watch development. The other filtering I have later really makes this quite useless, but it just speeds things up a little bit if you can strip down the list of devices before doing lots of i/o

After that, I populated a list of apps 

The only particularly interesting thing here is that i do a wildcard search of al application info.plist files and parse them for their bundle identifiers. You could also parse them for the app name to display instead of the bundle identifier. However if you release the same code in different regions under the same name (using different bundle identifiers to release to the different regions at different times of the day) then you might have duplicates, making the bundle identifiers more convenient.

The key here is that if you have the bundle identifier, then you can run an xcrun command to just get the full path to that app’s data directory. You can avoid the whole mess of non-deterministic paths

Once you have the device objects and their bundle identifiers, it really is quite easy to throw together some simple i/o prompting

The final script is attached, but I don’t think it needs to be gone into further detail.

simdir

Leave a Reply

Your email address will not be published. Required fields are marked *