From an app to a Super App

Part 3: How to manage environments in to an App with frameworks

Adapting like a chameleon

--

During the development process, it is very important to know which data you are working with, so you have to have development environments within the project. Xcode init the project with Debug and Release environments by default, but you can add as many environments as you want and configure them.

For this new episode of How to create a Super App and not die trying, we are going to talk about environments: how to configure them within our project, how to configure them in our frameworks and how to configure the environmental framework in our project.

We are going to continue developing our School Project and create environments using the configuration options of the project and using the compiler custom flags that Swift provides us. This is not the only way of creating an environment, there are more ways of creating and managing environments like XCConfig (Xcode Configuration File), but in this post we are not going to explain them or to talk about the differences between them.

How to create, configure and use environments into a framework

Open Student Framework and select the project, go to Info tab and in the Configurations section we can see the Xcode default environments: Debug and Release. Let’s create a new one duplicating Debug environment. We will call it Prerelease.

Student Framework Configurations

Now, open Build Settings tab, look for ‘Swift Compiler — Custom Flags’ and open the variable ‘Active Compilation Conditions’, where all the configurations are available. We have to give a name to those environment variables:

Student Framework Swift Compiler Custom Flags

Active Compilation Conditions is a build setting which allows us to define our flags without the need to prefix them.

The next step is to open StudentHomeViewModel, where we are going to create a method to print in console the environment we are using at this time.

We call this method from StudentHomeViewController on the system method didLoadView(). To check the environments, we have to modify the StudentApp scheme and select the environment we want to launch.

Student App Scheme

If we launch the Student App selecting the different environments we obtain the following message on the console of Xcode:

How to create, configure and use environments into the main project

Now that we have our framework ready to work with environments, we have to configure our main project to work in the same way. The point we want to achieve is that we want to have one app for each environment, so we are going to create different targets on the School App. By this way, each target will be a different environment and it will be easy to work with them.

A target specifies a product to build and contains the instructions for building the product from a set of files in a project or workspace.

First step is to create the Prerelease environment like we did before in the Student Framework. Go to Project -> Info -> Configurations and duplicate Debug. Like before, open Build Settings, look for ‘Swift Compiler — Custom Flags’ and give the same names to the environment variables in ‘Active Compilation Conditions’.

To check the environments, we have to repeat the same process of adding a method in the SchoolHomeViewModel, so repeat the process explained before by adding the same code as in StudentHomeViewModel.

Manage School environment

The second step is to create a target for each environment. Click the right mouse button over the School Project target and duplicate it. Change the name to SchoolProjectDebug.

Create a new one for Prerelease target repeating the process and name it SchoolProjectPrerelease. Xcode has created the new Info.plist files for these two new targets outside the project folders so we have to move them to the correct folder. Pick those two new files, move them to the same path as the original Info.plist file and rename the files to InfoDebug.plist and InfoPrerelease.plist:

School Project folder

Now you have to indicate on the project where those files are for the new targets: select SchoolProjectDebug target, go to Build Setting tab and search “Info.plist file”. Set the current path for the files. Do the same for Prerelease target.

School Project Build Settings

The next step is to configure the targets for managing the correct environment. School Project uses Release config, SchoolProjectDebug uses Debug config and SchoolProjectPrerelease uses Prerelease config.

School Project Scheme

As we have created new targets, we have to add them to the pod file to install the dependencies, so the pod file will be like this:

School Project Podfile

Let’s work together

Now that all is ready, run ‘pod install’ on the terminal and launch the School Project Debug scheme. If you navigate through the app, the terminal will print the messages configured in the School App and in the Student Framework:

When we launch the Prerelease scheme and navigate through the app, the Student Framework prints in Xcode terminal in incorrect environment:

This is because when we install the pod, CocoaPods does not maintain our project settings: if we go to Pods project in the project navigator, open Student Framework and search ‘Swift Compiler — Custom Flags’ in Build Setting, we can see that the configuration disappeared. To solve this, we have to add the following code inside our pod file:

School Project Podfile

Be careful of managing correctly the configuration names.

This code looks for the targets of the app pods and gives a value for the configuration variable according to the configuration that we have put. Once we have this, we run ‘pod deintegrate’ and ‘pod install’ again on the Terminal, relaunch the Prerelease Scheme and get the expected result.

Finally, we launch the Release environment and we have the following result on the Xcode console:

What’s next

You can find the source code of the example on GitHub.

We have created different targets for managing different environments for our project and for our framework, and we have connected them maintaining the same environment. As I explained at the beginning of the post, this is an example of doing that. If we want to manage URLs for each environment or keys and tokens, it is more secure to use XCConfig files because the keys and tokens are not on the code.

In the next post we will see how to manage dependencies between developing frameworks and manage dependencies between our frameworks and others libraries.

--

--

Juantri Jiménez

Spanish iOS software engineer. I write about features of Swift and iOS development practices