Reference Xcode Configuration Variables in Objective-C

When I pointed out that Sparkle finds its XPC services on its own, I mentioned you can see how it does this by searching for "SPUXPCServiceExists".

If you take a look at the use of this function, you'll see something like this in the Objective-C (!) source files:

if (!SPUXPCServiceExists(@DOWNLOADER_BUNDLE_ID)) { /* ... */ }

What is @DOWNLOADER_BUNDLE_ID?

It's taken from the project configuration file CommonConfig.xcconfig, where it reads:

DOWNLOADER_BUNDLE_ID = org.sparkle-project.Downloader

That's not enough to make the configuration constant available in code. You also need at least this, preferably in the same file:

GCC_PREPROCESSOR_DEFINITIONS_COMMON = DOWNLOADER_BUNDLE_ID=\"${DOWNLOADER_BUNDLE_ID}\"

This will make the variable accessible in Objective-C code. Nice!

But you can reference is only from Objective-C.

Sadly, since Swift 2.2, you cannot use them directly in Swift anymore without defining constants in Objective-C, first. Swift doesn't include a preprocessor (see on the Apple Swift blog here and here for explicit mentions of that fact).

Since Xcode 8 we have SWIFT_ACTIVE_COMPILATION_CONDITIONS to set flags like BETA or DEBUG for conditional compiling, but you cannot set string values this way, it seems. Previously, we'd have set OTHER_SWIFT_FLAGS to -D DEBUG to define a flag as being present. The compiler does not complain if you add FOO="bar", but it doesn't do what you may think it does: it only sets a flag of this exact weird name to "on".

Browse the blog archive