Having 2 or 3 targets in your project is nothing special. What if there are 40?

In our last iOS project for Audiojoy.co, we had about 40 similar apps with the identical logic but different contents. In this article, I describe how we at Uptech simplified the development process.

Every app is a different product. So first, we reduced the number of the app-specific items to the minimum. All apps shared the majority of the code and resources like sounds, storyboards and the global asset catalog. Still, they were not completely identical. So we had to use some specific techniques to make this work.

Configure app structure

We added a configuration plist to store some key properties there. Among them, there’s a description of the app’s main menu and a set of view controllers available through it. This makes configuring the app structure pretty easy. The list of the view controllers has the following format:

Knowing the name of the storyboard file and the identifier of the required view controller, we simply instantiate all of them one by one in our app coordinator (SMPScreenModel class encapsulates the data from the plist):

CODE:https://gist.github.com/annakorolyova/093d99ed87ecba6bb5f156306d9eb769.js

https://gist.github.com/annakorolyova/093d99ed87ecba6bb5f156306d9eb769.js

Write scripts

Once, having to make some changes to the UI design, I needed to add a dozen of fonts to every one of my targets. In such situations, the PlistBuddy tool comes to help. PlistBuddy is a command-line editor for plist files. It allows working with plists using simple commands like Add, Set, Delete. You can find a great guide here.

For example, here are the commands you use to add a Photo Library usage description to a test.plist file:

/usr/libexec/plistbuddy test.plist
Command: add :NSPhotoLibraryUsageDescription string ‘to save images’
Command: save

PlistBuddy accepts commands as arguments from the command line. So we can write a script to edit each Info.plist in the project directory:

CODE:https://gist.github.com/annakorolyova/4748abe463bfd90ff83d99c5a1babde2.js

https://gist.github.com/annakorolyova/4748abe463bfd90ff83d99c5a1babde2.js

Now we can set the description string for each app by just calling

. set_photo_library_usage_description pathToMyProjectFolder

Duplicate targets

Creating a new target might take some time if you have a lot of code and resource files.

In our project, we use a few template targets to simplify and unify the process of creating new products. Templates are regular targets but without the app identity. They have neither an Info.plist file, nor any specific resources. But they include all the shared code as compiled sources, libraries and frameworks, custom scripts, CocoaPods settings, and bundle resources. Having such template, you only need a few steps to create a new product:

  • duplicate the template target;
  • add an Info.plist to it;
  • create a scheme;
  • set new app icons and launch images;
  • optionally add app-specific resources;

And you’re ready to go!

Sometimes we remove old targets from the project to reduce the number of checkboxes in the target list of the XCode Add file window. For whatever reason, you don’t have an option to check all of them, which can be really annoying in such projects. If you happen to know how to avoid checking all of them one by one, I’d really appreciate an advice!

Conclusion

A project with multiple targets is potentially a big mess. And the more differences you have between your products, the more chances are that at some point you’ll find yourself not capable of handling all of them properly in one project. In our case, those differences were mainly connected to the content of the apps. More often, there are also differences in functionality, which raise more challenges. However, with some useful tools and tips, developing a multi-target project can become easier and faster.