-
Notifications
You must be signed in to change notification settings - Fork 7
Environments
We usually need to use different settings and parameters for different environments. For example API URLs, tokens and keys for 3rd party services, plists for Firebase etc. Our template contains complex set of tools to easily resolve this common issue.
Scheme == Environment

You can see 3 schemes in Xcode project. There is a special scheme for each environment. We usually use these 3 environments:
- Development - for development 💡
- Stage - for testing, QA, presentations for our customers
- Production - for AppStore
Each scheme contains a short pre-build action with 2 commands. At first environment info is written to a hidden file which is then used in build phases. That's because you have no info about running scheme (and scheme == environment) in build phase, so we pass it through a file. Second action is a generation of a plist preprocess header. This must be done in scheme pre-action to have header available before build starts. Otherwise build would fail.

Each environment can be built with 3 different build configurations:
- Debug - for running on dev's device
- Beta-Developemt - builds for QA with development API
- Beta-Stage - builds for QA with stage API
- Beta-Production - builds for QA with production API
- Release
Besides different build settings like optimization level, bitcode etc. there is a different bundle ID for each configuration. We usually use this pattern:
- Debug -
cz.ackee.appName.debug - Beta-Development -
cz.ackee.appName.development.beta - Beta-Stage -
cz.ackee.appName.stage.beta - Beta-Production -
cz.ackee.appName.production.beta - Release -
com.company.appName
It is tied with code signing settings and it also allows you to install eg. debug and appstore versions on one device.
There are 3 build phases connected with environment switching.
Folder Environment contains folders for all environments. This script copies all files from selected environment's folder to folder named Current, where files from Current are linked/bundled to project.
Our template contains only one file now - environment.plist and folder with Google plists, but you can add more of course.
File environment.plist mentioned above is the place for your base URL, tokens etc. In this build phase swift enums are automatically generated from this file so all environment variables are accessible in your codebase as enum cases (see file Environment.swift).
The generator script supports almost all value types that plist can hold, but there are some conventions.
Supported types:
-
Dictionary- generated as nestedenum, first letter is capitalized -
URL- string whose key has suffixURLand can be converted toURL -
Bool- bool or number whose key has prefixisand can be converted toBool(plist serialization cannot determine betweentrue/falseand0/1) IntDoubleDateData
We (and a lot of other developers) use Firebase in our apps and as you know, Firebase is configured via downloaded plist file. This file is unique for each bundle ID so we need 3 different plists.
But when you need to use eg. Firebase realtime database in different environments you need more then one firebase project.
That's why we have GoogleService folder with 3 plists in each environment folder. This folder is copied within environment switching phase. In this phase the right file is selected according to build configuration. It's just copied to GoogleService-Info.plist.
Continue to Extensions ➡️