Skip to content

417-72KI/BuildConfig.swift

Repository files navigation

BuildConfig.swift

Actions Status Version Platform GitHub release Swift Package Manager GitHub license

BuildConfig.swift is a tool to generate configuration files by merging yamls or jsons.

By splitting the file for each type of setting, it is possible to prevent conflicts of configuration files.

Also, by splitting the file for environment configurations, it will be easier to overwrite configurations for each environment.

Example

Important

There was a problem that parsing 0 or 1 should be Int, but Bool actually.
Since 5.2.0, keys for Bool must have is prefix.

This restriction will be fully resolved since 6.0.0.

Base JSON file

{
    "API": {
        "domain": "http://localhost",
        "path": {
            "login": {
                "method": "POST",
                "path": "/login"
            },
            "getList": {
                "method": "GET",
                "path": "/list"
            }
        },
        "version": 1
    },
    "is_debug": true
}

Call above configuration

Vanilla

let file = Bundle.main.path(forResource: "Base", ofType: "json")!
let data = try! Data(contentsOf: URL(fileURLWithPath: filePath))
let config = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
let api = config["API"] as! [String: Any]
let domain = api.domain as! String // "http://localhost"
let loginPath = (api.path as! [String: Any])["login"] as! [String: Any]
let path = loginPath.path // "/login"
let method = loginPath.method // "POST"
let apiVersion = api["version"] as! Int // 1
let isDebug = config["is_debug"] as! Bool // true

Using BuildConfig.swift

let config = BuildConfig.default
let domain = config.API.domain // "http://localhost"
let path = config.API.path.login.path // "/login"
let method = config.API.path.login.method // "POST"
let apiVersion = api.version // 1
let isDebug = config.isDebug // true

Installation

Common

  • Create directory for splitted configuration files, e.g. $PROJECT/Resources/BuildConfig.
  • If you use different settings for each environment, create folders with the name for each environments into above directory.
  • You don't have to add above directory into project.

Example

BuildConfig
│ ├ debug
│ │ └ c.yml
│ ├ adhoc
│ │ └ c.yml
│ └ release
│   ├ a.yml
│   └ c.yml
├ a.yml
├ b.yml
└ c.yml

SwiftPM(6.0.0~)

Important

In this case, there are some constraints.

  1. directory name must be BuildConfig
  2. filename of environment settings must be match with Configuration name with snakenized.
    examples:
    • "Debug" -> debug.yml
    • "AdHoc" -> ad_hoc.yml
    • "Release" -> release.yml
  1. In Project Settings, on the tab "Package Dependencies", click "+" and add github.com/417-72KI/BuildConfig.swift
  2. Select your target, on the tab "Build Phases", in the section "Run Build Tool Plug-ins", click "+" and add BuildConfigSwiftGenerate
  3. Build your project, now the BuildConfig struct should be available in your code.

CocoaPods

  • Add the following line to your test target in your Podfile:
pod 'BuildConfig.swift'
  • Add the following Run script build phase to your test target's Build Phases:

Example

if [ "${CONFIGURATION}" = 'Release' ]; then
  ENVIRONMENT='production'
else
  ENVIRONMENT='staging'
fi

"${PODS_ROOT}/BuildConfig.swift/buildconfigswift" -e $ENVIRONMENT "$SRCROOT/$PROJECT/Resources/BuildConfig"

You can replace "$SRCROOT/$PROJECT/Resources/BuildConfig" to the relative path from project to the directory you created.

Also, you can add -o option with output path to specify where BuildConfig.plist and BuildConfig.generated.swift will be created.

  • Add $(SRCROOT)/BuildConfig.generated.swift into Output Files in above Run script build phase.

    • If you set a path to output generated files by -o option, you have to change Output Files to it's path.
  • Drag the new Run Script phase above the Compile Sources phase and below Check Pods Manifest.lock.

  • Build your project, in Finder you will now see a BuildConfig.generated.swift in $SRCROOT or a path you set with -o option in above Run script build phase.

  • Drag them into your project.

Tip: Add the *.generated.swift pattern to your .gitignore file to prevent unnecessary conflicts.

What is BuildConfig.swift doing?

  • Detect all yml/json files in $SRCROOT/$PROJECT/Resources/BuildConfig (exclude in child directories).
  • If the -e option is set and a directory with the same name as that option exists in $SRCROOT/$PROJECT/Resources/BuildConfig, all yml/json files in the directory are read.
    For example, -e staging option means to read $SRCROOT/$PROJECT/Resources/BuildConfig/staging/*.{yml/yaml/json}.
  • Parse above files as Swift.Dictionary.
  • Deep merge the above dictionaries.
  • Output merged dictionary as a JSON data.
  • Generate struct from merged dictionary and enable to decode JSON data in above.

Libraries

License

Available under the MIT License.