What's the difference between Build Configurations and Targets?

1.9k views Asked by At

We have five practically identical apps, with a few different icons/names/settings. They are different "brands" of the same app, only differentiated in a few different icons, separate AppGroups, and a few default settings in code. These are created as their own targets in Xcode. It's one codebase, but 5 targets pointing to it.

It started out looking really nice, with five different targets. However, we have now added two extensions to the app. One custom "NotificationContentExtension", and one "TodayExtension"(Widget). Since we have 5 different targets with 5 different entitlements/groups, we found no other way to achieve this than to add these extensions to EACH target. Since an extension is another target, that means we now have 15 different targets.

We're now experiencing extremely slow compile-times, because every time we as much as open the storyboard, Xcode compiles the entire thing once for EVERY (main)target. I don't need to build my storyboard 5 times. Or any of my other files. I have ONE app, but a few different files, and a few runtime-settings.

This made me wonder - each and every one of these 15 targets have two build configurations by default: RELEASE and DEBUG. I noticed it's possible to customise these, and add more. Why not add configurations instead of targets?

E.g instead of "RELEASE" and "DEBUG", make them "MYAPP1", "MYAPP2", "MYAPP3" etc. Each configuration can have their own product name, icons, and whatever, right?

Are there any good reasons not to do this? Is it possible, when dealing with different AppGroups/Entitlements etc.? We have CoreData-databases stored in AppGroups. It is important that these apps can all be installed on the same device without being corrupted by each other. As far as I can think, this shouldn't be a problem as long as there are a few different FLAG's for each configuration, and customising the code as such. What about signing?

I read this article/tutorial on the subject, which explained the basics and got me started, but it will be a huge amount of work to actually test it with databases and entitlements and all.

1

There are 1 answers

0
Sti On BEST ANSWER

Answering a few years later: The answer was yes btw. Using BuildConfigurations is safe and works perfectly fine. It also removed all the unnecessary build times. We converted the project setup and ended up with three targets (app, widget1, widget2), and multiple BuildConfigurations.

To customize build configs, click on your project in the Project Navigator, then click on the blue "MyApp" (under PROJECT, not under TARGETS), then select "Info" in the top bar. You'll see a list of your configurations. They'll be "DEBUG" and "RELEASE" by default. You can add/remove/customize here. Make it "MyApp1", "MyApp2" and "MyApp3". Then click on your "MyApp" under "Targets", go to "Build Settings", and search for e.g "Product Name". If you hover over it, an arrow will appear next to "Product Name", click it to expand it, then you'll see you can change the value individually for your different configurations, so "MyApp3" can be named "MyApp3" without affecting the others. This can be done for all Build Settings.

If you have several "flavors", and potentially have to add more later, I recommend NOT changing the individual values directly in "Build Settings", as they're harder to find and easier to forget. You should rather make each relevant value (such as ProductName) inherit from an external key, and create your own .xcconfig-files for each "flavor", which contains all the individual values for these keys. That way, if you need to add another flavor, you can simply add another .xcconfig-file which has all the relevant changes, and you don't have to look through all values in BuildSettings and potentially forget some of them.

When you've done this, to be able to actually build/run each configuration, you'd have to add a scheme to each config.

The only negative side effect I've noticed from this approach is that the app's icon in the scheme-dropdown-list is wrong. They'll all be the same, even if the "App Icon Set Name" is different. The app's icon will be correct when run/installed, but it will display wrong in Xcode's built-in drop-down-list.

Be careful though, you should know what you're doing when changing the build-settings. By default, when you run an app, the DEBUG-config runs, and RELEASE is used for when you "Archive" (when you release). If you don't respect the differences between these two, and just create ONE build config for each of your apps/flavors, you'll either get longer build-times when developing, or poorer performance after release. This is depending on build settings like "Optimization Level" etc. So to be safe you should create "MyApp1DEBUG" and "MyApp1Release" for every app, which are clones of the original "DEBUG" and "RELEASE" respectively.