In the last few months twice I've wanted to access the source code of our application. The first time I did it I came up with a pretty neat hack, but it wouldn't really work in many places. The second time however, I asked the internet, and the internet replied.
TLDR: You can use your project's scheme to expose derived Xcode environment variables to your source code.
The rest of the blog post is a little bit about why I wanted to do that and what I did with it.
Both times I've wanted to access the source code of our apps is because I've wanted to make better admin tools. It should come as no surprise to people who know me that I care about tooling, but I also care a lot about making it possible for our admins to do their own thing. As such, our admin settings panel in Eigen is extensive.
Root React Components
The first time came when I started to think about what admin options I'd like to see for people using our React Native side. These are the options I came up with:
There are two interesting things about it:
- We support running any master commit of our React Native code inside Eigen, for Admins, via AppHub
- We allow loading arbitrary React components as an admin.
It's this last bit that's interesting, right now I'm working on a new root Gene component (read: new view controller) in Emission, our React Native implementation. As this work has not moved upstream into Eigen, I can access it through a commit on AppHub, and then open it using our custom module loader:
In order to show the available root components (Artist/Home/Gene), we use GitHub's raw URLs to download the source code of our Open Source apps. Hah, a nice hack right? I created a
ARAdminNetworkModel with an API like this:
1 2 3 4 5 6 7
Which simply uses
NSURLSession under the hood:
1 2 3 4 5 6 7 8 9 10 11
Nothing special, but it required a cognitive jump to get there.
The second time I wanted this is inside the example app for Emission. This is a typical example application for a library made by
pod lib create. This example app is basically just the admin settings panel from Eigen, shown above.
When I switched the example app to use a similar theme and menu DSL as Eigen, I also took the chance to expand on the buttons we had available. Previously there was the ability to load the view controller for one specific artist, but I knew we had a giant list of artist slugs inside one of our optional sub-modules. What I wanted to do, was offer a random Artist from that if the submodule was
This required introspecting the source, which I could have also done via the GitHub API, but it was also feasible to do by accessing the filesystem outside of the simulator. This is totally possible ( and is how FBSnapshots works ) but I needed to access the project root, then I could build relative links. Thus, I asked the internet. I knew these variables existed, but that they were a part of the build process - and not exposed to the app runtime.
There are two ways to do it, both make sense for different contexts:
- Baking the value into your Info.plist - which makes it available for all consumers at runtime, e.g. you could deploy this value, but it's not too useful for my problem.
- Exposing it as an environment variable via your scheme - perfect for this case, the variable won't be exported when you deploy.
Now our scheme looks like this: