Ad

Our DNA is written in Swift
Jump

Target-specific Headers

Often you will add multiple targets to your project file to build variants of the same app. For example if you have a Lite version or Ad-sponsored variant using the same source code you would definitely save yourself a lot of work having a single project and then multiple targets.

While I was helping a colleague merging three projects into one we found it impossible to assign headers to single targets. You can assign source code, images and lots of other file types, but why oh why no headers? How would we make sure that from 3 Constants.h files always the correct one would be used?

There are of course methods out there which propose to either have a script replace the headers or use an ugly contruct like this:

#if defined(TARGET_1)
#import
#elif defined(TARGET_2)
#import
#else
#error Must define a TARGET macro!
#end

I you you too are cringing from seeing such code. Surely there must be a more elegant solution. I searched, and I found not one but TWO.

Consider the following layout of your project directory: You have two headers by the same name header.h in two subdirectories called Header1 and Header2. 

Same Header multiple times

Depending on the target you want to use the appropriate header.h file.

Method 1 – Set User Header Search Path

In the build settings of your target (right-click, Get Info, Build) you need to set  the “User Header Search Paths” to the subdirectory specific to this target. If Header1 is directly below your project directory you can specify just “Header1”. In any case you can be really safe by specifying the absolute path using the variable for the project directory. I don’t advise really writing the absolute path there because this would stop working if you move your project somewhere else.

Method 1

I also had to put a checkmark next to “Always Search User Path” for this to work. 

$PROJECT_DIR

If you enter ${PROJECT_DIR}/Header2 then in the build settings you will expand the variable to the real path.

Method 2 – Target-specific Precompiled Header File

XCode always puts the Prefix Header YourApp_Prefix.pch at the top of all your source code files. Imports you put there you don’t have to put in all your files. The default is to have a single PCH importing the foundation framework and UIKit. That’s why you don’t have to keep importing UIKit and Foundation but still can use those things in your code.

Make one such file per target, copy over the standard imports. Then also add an import for your specific target-specific header.

#ifdef __OBJC__
    #import 
    #import 
#endif
 
#import "Header1/header.h"

 

Now you only need to change the “Prefix Header” name in the target’s build settings and you’re done.  

Method 2

The major advantage of the second method is that you don’t have to think about including your target-specific header all the time. The definitions inside will always just be available.


Categories: Recipes

Leave a Comment