Xcode Construct Configuration Information – NSHipster


Software program improvement finest practices
prescribe
strict separation of configuration from code.
But builders on Apple platforms
typically battle to sq. these pointers with Xcode’s project-heavy workflow.

Understanding what every venture setting does
and the way all of them work together with each other
is a talent that may take years to hone.
And the truth that a lot of this data
is buried deep throughout the GUIs of Xcode does us no favors.

Navigate to the “Construct Settings” tab of the venture editor,
and also you’ll be greeted by tons of of construct settings
unfold throughout layers of tasks, targets, and configurations —
and that’s to say nothing of the opposite six tabs!

Xcode build settings

Fortuitously,
there’s a greater option to handle all of this configuration
that doesn’t contain clicking by a maze of tabs and disclosure arrows.

This week,
we’ll present you the way you should utilize text-based xcconfig recordsdata
to externalize construct settings from Xcode
to make your tasks extra compact, understandable, and highly effective.


Xcode construct configuration recordsdata,
extra generally recognized by their xcconfig file extension,
permit construct settings in your app to be declared and managed with out Xcode.
They’re plain textual content,
which suggests they’re a lot friendlier to supply management techniques
and may be modified with any editor.

Essentially,
every configuration file consists of a sequence of key-value assignments
with the next syntax:

BUILD_SETTING_NAME = worth

For instance,
to specify the Swift language model for a venture,
you’d specify the SWIFT_VERSION construct setting like so:

SWIFT_VERSION = 5.0

At first look,
xcconfig recordsdata bear a placing resemblance to .env recordsdata,
with their easy, newline-delimited syntax.
However there’s extra to Xcode construct configuration recordsdata than meets the attention.
Behold!

12 Issue App philosophy,
then they’ll have separate endpoints for
improvement, stage, and manufacturing environments.

On iOS,
maybe the most typical method to managing these environments
is to make use of conditional compilation statements
with construct settings like DEBUG.

import Basis

#if DEBUG
let apiBaseURL = URL(string: "https://api.staging.instance.com")!
#else
let apiBaseURL = URL(string: "https://api.instance.com")!
#endif

This will get the job finished,
however runs afoul of the canon of code / configuration separation.

An alternate method takes these environment-specific values
and places them the place they belong —
into xcconfig recordsdata.

// Improvement.xcconfig
API_BASE_URL = api.staging.instance.com

//////////////////////////////////////////

// Manufacturing.xcconfig
API_BASE_URL = api.instance.com

Nonetheless,
to tug these values programmatically,
we’ll have to take one extra step:

bundle.
Due to this fact,
by including references to $(API_BASE_URL),
you’ll be able to entry the values for these settings
by the informationDictionary property of Basis’s Bundle API.
Neat!

Xcode Info.plist

Following this method,
we would do one thing like the next:

import Basis

enum Configuration {
    enum Error: Swift.Error {
        case lackingKey, invalidWorth
    }

    static func worth<T>(for key: String) throws -> T the place T: LosslessStringConvertible {
        guard let object = Bundle.essential.object(forDataDictionaryKey:key) else {
            throw Error.lackingKey
        }

        change object {
        case let worth as T:
            return worth
        case let string as String:
            guard let worth = T(string) else { fallthrough }
            return worth
        default:
            throw Error.invalidWorth
        }
    }
}

enum API {
    static var baseURL: URL {
        return strive! URL(string: "https://" + Configuration.worth(for: "API_BASE_URL"))!
    }
}

When seen from the decision website,
we discover that this method harmonizes superbly
with our greatest practices —
not a single hard-coded fixed in sight!

let url = URL(string: path, relativeTo: API.baseURL)!
var request = URLRequest(url: url)
request.httpMethodology = methodology

Xcode tasks are monolithic, fragile, and opaque.
They’re a supply of friction for collaboration amongst crew members
and usually a drag to work with.

Fortuitously,
xcconfig recordsdata go a protracted option to deal with these ache factors.
Shifting configuration out of Xcode and into xcconfig recordsdata
confers a mess of advantages
and affords a option to distance your venture from the particulars of Xcode
with out leaving the Cupertino-approved “comfortable path”.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles