Using xcconfig files for your XCode Project

Using xcconfig files for your XCode Project

Ctrl + D

If you have ever been stuck with project file conflicts in a multi collaborative developer environment in XCode it might be worth while adopting xcconfig files. My experience is that it reduces project file conflicts by moving build settings into separate files which are version tracked independently. I was first introduced to the concept many years ago at a local CocoaHeads meeting but didn’t take much notice of it at the time. Later on I was re-introduced to the benefits of this approach by my good friend Edward Patel (www.memention.com). So what is xcconfig files all about and how can you adopt them in your workflow?

Working as a developer you sooner or later will have to mess with the projects build settings. It might be that you have to link to added frameworks or static libraries, or that some of these need you to set other C flags or whatever. Doing so changes the project file, and even though the structure of the project file has greatly improved over the years, you often end up solving project file conflicts manually. By moving these settings to explicit xcconfig files and telling XCode to use these xcconfig files for the build process, your changes never really messes with the project file, but instead you make changes to these Key-Value text files. The (rare) merge conflicts are easier to solve, and the overall build settings get, in my opinion, a lot easier to get a grip on.

It takes some setting up, and in this little tutorial I hope to show you how this can be done from scratch, hopefully giving you a better understanding of how you can use xcconfig files in your workflow.

The steps presented here are based on a clean project, but nothing stops you from adopting this workflow in an existing project. However, good to know is that some resource management systems, like CocoaPods, uses xcconfig files to do their magic, and therefor can mess upp your own beautiful structure. Be aware and evaluate if this is still worth the while…

NOTE! See update at end of the article on CocoaPods and custom XCConfig files!

Of we go!

Start by creating a new single view application project. I name it ConfigDemo. Having saved it in a convenient location on your disk your project files overview should look something like this:

Project Overview

I like to add my files in a dedicated folder on the drive to keep things clean and tidy. Ctrl click on the project name (ConfigDemo at the top of the overview) and choose “Show in Finder”.

Project Folder

Make a new folder and name it Config.

Config Folder

Drag the newly created folder back to the project so that you have a folder in you project with a direct reference to the folder in the Finder. Accept in the sheet that is presented.

New Project Overview

 

We will need a couple of config files. One for the general settings of the project, preferably named the same as the project. And we need one for each target in the app. In this demo we will do with the two targets created by the project (debug and release) and we wont bother setting up the test target this way, but if you work with TDD and therefor uses the test target and/or if you have a separate target for AdHoc distributions or whatever, of course you should make xcconfig files for all of these targets. So, Ctrl-click the Config folder in the Project navigator. Choose New File. Click “Other” and select the Configuration Settings File.

Create Config File

Name the file the same as your project. Make sure it is saved in your Config folder (we want to keep this nice and clean, right) and notice that these files should not be added to any target! Repeat the process and create two new files, Debug and Release. Your Project Navigation should look something like this when you’re done. All Config Files

Selecting any of the xcconfig files, you see that they are nothing by empty text files, apart from the ubiquitous copyright comment. Now you need to let XCode know that these files should be used for building your project. You do so by selecting  the project in the navigator (like in the image above). You are probably familiar with the project / target navigation that is presented in the main editor area.

Projects and Targets

Start by localizing the Configuration settings. You should by default have a Debug Configuration and a Release Configuration and both of these should have the “No Configuration Set” in their “Based on Configuration File” column.

Configuration Settings Default

Press the disclosure triangle next to Debug. You will see a list with the project followed by target and test target for the Debug build.

Configure Debug

Press the “None” menu on the row with your project name (ConfigDemo in my case) and choose the xcconfig file for you project. Repeat the process for the main target and choose the Debug file (ignore the test target for now). Also repeat the process for the Release Target. You should end up with a configuration that looks like this.

All Config files set

Now you are set to start moving settings from the Project file to the xcconfig files. But how is this done? I mentioned that these files are Key-Value text files, but which keys should be used, and which values are valid? Well we start by diving into the Build Settings of the Project. With your project selected in the left part of the editor, select the Build Settings Tab in the top of the editor.

Build SettingsMake sure the Levels tab is selected in the top of the table. You will find a long list of build settings for you project. There are many columns here that give you a hint of what XCode will use as the build setting in each individual case.  So far, and with a clean xcconfig file for the project, you should see three columns, Resolved, ProjectName and iOS Default. A beautiful feature here is that by selecting a setting and pressing Cmd-C (as in copy) you will copy a text version of the setting which, tada, suits the xcconfig file like the hand in the glove. So go on and select the Base SDK line, and press Cmd-C. Now select the config file for the Project and paste.

Config File First Paste

How convenient! Not only did XCode provide you with the Key and the value, it also gave you all the setting for each target. But here we have exactly the same setting for both targets, is that really necessary? Answer is no. So now you can start cleaning up your xcconfig file. Remeber to save the file. The final result should look like this.

First Config Setting

 

Going back to the Project Settings table, you now should see a fourth column, namely that of you config file.

Build Settings With xccofig file column

Also note that in gray, the same setting is found in the Config.File column as in the ConfigDemo column. Also note that the ConfigDemo setting is marked in green. This is an indication that though we have set this setting in the config file, the default Project setting is trumping the settings of the config file. This is important to note, as XCode prioritizes settings from right to left. And the Resolved column shows the final result. So how do you make XCode use the settings in the config file? Easy! Press Delete with the row selected and the default setting of the Project will be deleted. You will now see that the xcconfig file settings is marked green instead.

Config File Setting Marked

Now, the next setting “Build Active Architecture Only” is trickier. Here we have multiple values for the targets. The iOS Defaults is set to “No” yet the debug target is set to Yes. Perhaps this setting should be placed in our config file for the target instead. Remember we created a separate config file for each target? Now in the detail navigation to the left select the ConfigDemo Target instead of the Project. You will se a new column appearing to the far left with a target icon and the name of the Target (same as the project, in this case ConfigDemo)

Target Selected

Note that since the target setting column is to the left of the Project settings Columns, the target settings always Trumps the Project settings. This is great because you can sett general settings for the project and put target specific settings where appropriate. A great way to keep it all nice and tidy. Now reselect Project in the detail navigator. Then select the “Build Active Architecture Only” row and press Cmd-C again to copy the settings.

Copy Project Settings

Note that you need to have the Project selected to get the right settings. Having the same row selected, but from the Target does not copy the correct value. Now select you Debug config file and paste the result.

Debug Target

 

Clean up!

Debug Target Clean

Now Select the Project in the Project Navigation and the Target in the Detail Navigation. You should now see that the target config files column is visible with the settings we just pasted into our targets config file.

 

Note that the targets config file is already marked in green, showing that it trumps the Project Settings. But for the sake of tidiness, we mark the Project and delete the Project Settings in the same way we did previously.

Delete Project Row Settings

 

Returning to the Target we now see that the Project Column is clear of settings.

Project Settings Cleared

So, this is it basically. Going through all the setting in the table, you will see that there are Target Specific settings in the Project File as well as Project Specific settings like the once I’ve shown here. Have a look at Runpath Search Paths for instance.

Runpath example

This setting is Target specific, and following the same procedure as above, you can easily copy out all these target specific settings and place them in the appropriate target file. A note of causion though. Adding external frameworks for instance will require you to add entries to you build settings. If you normally do so in the build settings menu, remember to add them to the config files instead, to keep all settings in the right place. Might seem obvious, but a friendly reminder for the future.

So now you would go through the entire list and move all settings of the project from the Project File to the xcconfig files, placing them in the files most appropriate to your workflow. Normally you would end up with a rather fat xcconfig file for the project with minor tweaks in the respective targets xcconfig file. Which makes it easy to overview and maintain.

Finally, you can use these config files for other settings as well. Say for instance that you want to put you Facebook App Id in the config file with your custom key APP_FACEBOOK_ID and retrieve it from you info.plist, this value can be accessed by wrapping it in curly bracers and the $-prefix.

Facebook Id

Plist File Usage

 

Good luck and happy configuring!

Edit: CocoaPods actually rocks really great with custom config files, what you need to do is add the path to the CocoaPods generated config files from your own xcconfig files. The CocoaPods generated files ended up in ‘/Pods/Target Support Files/Pods/’ so I added

#include "Pods/Target Support Files/Pods/Pods.debug.xcconfig"

To my Debug.xcconfig file and respective CocoaPods Files to the other xcconfig files accordingly.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值