6

I have an API key defined on my CI/CD platform like so:

export API_KEY="XXXXXXXXXX"

Is there a way I can somehow compile this variable with my build so that I can reference it in Swift and not have to worry about the variable being defined in the binary's environment at runtime? I can't use ProcessInfo.processInfo.environment obviously, because the API key is only defined in my CI/CD environment. I want to have my binary compiled with the key so that when I distribute my app the key is available to use.

My use case is that I want to avoid putting an API key in my git repository, and instead fetch it from the CI/CD platform when the build is generated. If there is a way to inject an environment variable that then gets compiled as part of the binary, that would be ideal.

6
  • Not really. One way or another, your app has to have it (in order to be able to transmit it to the API) Commented Nov 5, 2019 at 18:49
  • @Alexander you might be misunderstanding my request. I know my app has to have the API key somehow; I am not trying to avoid that. I just want to grab it from an environment variable when the app is built and have it compiled with the app if that is possible. Commented Nov 5, 2019 at 19:29
  • IDK about your CI platform, but at the worst, you can make a script that reads the CI env var, and stores it into a place that's accessible to your app. But "not have to worry about the variable being defined in the binary's environment at runtime" isn't possible. Commented Nov 5, 2019 at 19:38
  • @Alexander Just to be clear, when I say "binary's environment" I mean I don't want to define an environment variable from the binary's running directory (as I have no control over the environment variables present when the app is distributed, and do not want the API key stored in our git repository). For example, if I could somehow inject an environment variable into a Swift config class of some sort that gets compiled as part of the binary, that would be an ideal solution. Commented Nov 5, 2019 at 20:14
  • Your script could inject the api key into a place holder of a Swift class, like Sombre's answer shows. You could also just write it to an plist/xml/json/yaml/whatever file that will be bundled into your app, and read it from there at runtime. Commented Nov 6, 2019 at 0:07

1 Answer 1

4

You can do a pre-action script in Xcode build section Xcode pre-action build

Which will modify placeholder with the following code:

let apiKey : String = "<# THE_API_KEY #>"

Modify the code directly in the source file

Before each build.

And you can add another one if you have a production key in the Archive pre-action

Exemple

place the apiKey variable in the file you want to access it

In Pre-action do a script to remplace a place holder text like THE_API_KEY

The script will look like this

 cat $PROJECT/$PATH_TO_FILE | sed 's/THE_API_KEY/YOUR_KEY' > $PROJECT/$PATH_TO_FILE

Don't forget to clean the code to avoid put the API key in you commit

With a Post-action

cat $PROJECT/$PATH_TO_FILE | sed 's/YOUR_KEY/THE_API_KEY' > $PROJECT/$PATH_TO_FILE
Sign up to request clarification or add additional context in comments.

9 Comments

Would this enable me to reference apiKey in my other source files? I have a specific class in my application that handles API initialization which needs access to that API variable. It doesn't seem like the pre-action variable is globally scoped though, and thus not accessible in my other source files.
The apiKey is a global variable so you decide which access control you give it
Your script will modify the swift file where the variable is written, with the $PROJECTDIR Xcode variables
Variables that have a scope global/internal are accessible in all target source file If you want to restrict to a file use fileprivate
I am unclear about the usage you provided. Does the let apiKey : String = "<# THE_API_KEY #>" go in the pre-action run script? Or in the source file where I want to use it? Also, I have never seen the <# #> syntax before and didn't find it described anywhere in the Swift documentation, what does it do? It clearly has some special meaning and Xcode formats it differently when you type it, but I don't see it documented anywhere
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.