The iOS app ecosystem has evolved into an incredibly diverse landscape of products and approach. From simple, single-purpose utilities and games, to complex, multifaceted e-commerce experiences.
The increasing demand for comprehensive app experiences, and the inherent complexity involved in building such apps means more and more iOS developers, including independent developers, are finding themselves working on small or medium sized teams.
Unfortunately, the iOS development environment, for all of its improvements since its introduction, still presents a number of challenges that must be considered while working on projects with multiple developers.
At Raizlabs, it’s common for many of our client efforts to require several developers and a designer or two. We’ve felt and dealt with the pain, so we figured it might be a good idea to share what we’ve learned in the hopes that it may spare some frustration and give more time to build great software.
If you’re doing iOS development, or any software development for that matter, and you’re not using some form of source control, stop reading this right now and go learn Git, or any other source control system you fancy. Git seems to be the “Apple blessed” option, as it has first-class support in Xcode, and it is our preferred VCS.
When working on a team, you’ll want to avoid tracking files that are specific to your own environment. Xcode tends to generate a number of these types of files, but Git has a mechanism in the form of a special .gitignore file that lets you keep such files untracked.
Be sure to always create a .gitignore for each new project and look at this handy Objective-C .gitignore template created and maintained by the fine folks at Github.
Once you’re in the thick of things — coding, committing, and pushing — you’ll eventually run into situations where you’ll need to resolve merge conflicts (more on how to avoid some of the more hairy ones below). Personally, I prefer the command line interface to Git, but if you’re more GUI inclined, we suggest the fabulous Kaleidoscope by BlackPixel. You can configure an external tool to handle merging.
Code Formatting and Project Structure
Part of working effectively on a shared codebase is reducing surprises and avoiding ambiguity. The easiest way to do this in terms of code is to conform to strict style and format specifications. No one wants to hop onto a new project and spend time trying to decide where to put a new file, newlines and braces, or whether to use tabs or spaces. On a team, it’s important to set these boundaries, or else be left with a messy, unapproachable project.
It’s also important to codify your code formatting and style in a shared document or company wiki. New engineers should be introduced to this on day one, and it should be applied and enforced. For those of you who are lazy (all software developers?), you can use Uncrustify and its associated Xcode plugin to make auto-formatting a breeze. Or, if you feel like jumping ship on Xcode altogether, the very capable AppCode from JetBrains does an admirable job at auto-formatting code.
Lastly, organize and codify your project structure. There’s nothing more jarring than working on a project with multiple developers and each person is putting new files in the group/structure of their choosing. Be very aware that Xcode does not create physical directories when you create new groups. This means that you may have the nicest source hierarchy in Xcode, while a quick look at the file system or source control will reveal a root directory nightmare. You can remedy this by creating a skeleton directory structure before you start the bulk of your coding and dragging directories into the project, ensuring that you choose “Create groups for any added folders” in the dialog that appears.
.xcodeproj and .xib files
These two file types are the evil cousins of team-based iOS development. I’ve spent more collective time resolving merge conflicts in these types of files than any other file types. The primary reason being changes to these files are triggered upon a very long list of possible actions, thus making merge conflicts very likely.
Regardless of the feature you’re adding, you’ll probably be causing an edit that someone will have to resolve upon merge. So what can you do to reduce the amount of time spent wanting to claw your own eyes out at the sight of another .xcodeproj merge conflict?
Avoid touching the same XIB files.
The best way to do this is by ensuring that you do not overload these types of files with more than one view controller and by communicating with your team. If you are going to start editing an XIB that you think someone else may be touching, vocalize this fact. It’s always better to coordinate XIB changes upfront than to deal with a merge that ultimately will result in someone reverting their changes after the fact. In most cases, manually resolving XIB merges is a lost cause, so proceed with that in mind. Supposedly this has become more possible with Xcode 5, but so far nobody here has seen proof of that.
.xcodeproj files are a slightly more optimistic situation. In most cases, I’ve found that in a merge conflict situation, both changes can be taken and everything is good in the world. There are certainly situations where this may not be the case, so make sure you pay attention to the file structure particularly during a merge, and always build and run before committing a merge resolution.
And again, communicate with the team.
Especially when there are large sweeping changes being made to the project, like adding many files, restructuring the groups, or moving physical file locations.
Given merge challenges presented by some Xcode filetypes, integrate early and often. Regardless of which source control system you use, keep branches as short lived as possible. The longer you wait to merge that incredibly awesome new feature you’ve been toiling away at, the more likely it will be that someone has added, edited, or removed files you’ve also touched. This is unavoidable to some extent, but don’t cause yourself more pain and suffering than needed. Remember, the .xcodeproj file changes anytime files are added, removed, or even adjusted in the project structure (i.e. almost always).
Use Asset Bundles
Asset bundles are a wonderful new way to manage all the assets for your app. Introduced in Xcode 5, they are in essence a set of nested directories and JSON files that contain and represent asset metadata.
The amazingly awesome thing about this?
Multiple developers or designers can add new assets to the project without causing .xcodeproj merge hell. What’s more, you can create any number of asset bundles, giving you endless possibilities for better organizing and isolating your various concerns.
…And that’s it! Hopefully some, or all of these tips may help you as you embark on your journey towards team-based iOS development zen. The tools we have to work with as iOS developers are not perfect, but as long as you know where the limitations are, and are willing to communicate, you and your team will have no trouble avoiding the pitfalls while building great software.