Xcode Groups vs. Folder References

When adding a folder to an Xcode project, you can add it as a group or as a reference.

What’s the difference, and why would you choose one over the other? Each has advantages and disadvantages, some of which are quite subtle.

Groups

With groups, Xcode stores in the project a reference to each individual file. This can lead to problems:

  • The size and complexity of the underlying project file (project.pbxproj) can grow significantly, especially with multiple targets. Each new target has to duplicate all of the references. You also have to remember to set the proper target membership for each file. Plus there is a greater likelihood of SCM merge conflicts due to the larger and more complex project file.
  • Groups may bear no resemblance at all to the folder hierarchy on disk. You can have project folders in the Finder that don’t even exist in the Xcode project, and vice versa. Because of the mismatch, locating files can get confusing.
  • If you move a file or rename it outside of Xcode, the reference breaks and the file turns red. File management becomes a real pain.

In exchange for these annoyances, groups give you some advantages:

  • You can pick and choose which files on disk you want to appear in the project. There may be auxiliary files such as documentation that you don’t want to appear in the Xcode Project Navigator.
  • You get fine-grained control over target membership. You can, for example, exclude a single file from a target.
  • When building the product, Xcode flattens the group hierarchy and dumps all the files in the top level of the product’s bundle. You don’t have to specify the location in the hierarchy. For example, instead of:
    [UIImage imageNamed:@"Images/Icons/GoPago"];

    you can just do:

    [UIImage imageNamed:@"GoPago"];

    But this does mean you have to resolve conflicts if two images happen to share the same name.

Folder References

Folder references are simpler. You can spot a folder reference because it shows up in blue instead of yellow.

The benefits of folder references are:

  • Xcode only stores a reference to the folder. All of its files and subfolders are automatically added to the project. This keeps the project file smaller and simpler, with less chance of merge conflicts.
  • If you rename, delete, or move a file in the file system, Xcode automatically updates the folder reference to reflect the change. File management is thus far easier.
  • Because the folder hierarchy in the project matches the hierarchy on disk, they will not diverge over time and cause confusion.
  • You don’t have to worry about name conflicts because the directory structure is preserved in the product bundle. Two files can share the same name as long as they live in different directories.

So why don’t we always use folder references?

  • Target membership is coarse-grained. Either all of the files in the folder are in the target, or none are. (On the other hand, if you actually want all files in the folder to have membership, this could be more of a pro than a con.)
  • There is no way to hide individual files from the project navigator. Either they all appear or none do. (Again, this could in fact be an advantage because there’s no way for a file in the folder reference to be accidentally left out of the project.)
  • When loading a resource, you must specify the full path. Instead of:
    [UIImage imageNamed:@"GoPago"];

    you must do:

    [UIImage imageNamed:@"Images/Icons/GoPago"];

    And if you change the file’s location on disk, you must remember to update the code.

  • An image stored as a folder reference will not work with Interface Builder! When editing, IB is able to find the image file and allows you to select it, but when it generates the XIB, it strips the folder location, which prevents it from being found. The result is a blank image and a runtime error:
    Could not load the "MyImage.png" image referenced from a nib in the bundle with identifier "com.mytest.MyProject"

Conclusion

The fact that Interface Builder can’t work with images in (sub)folder references is a dealbreaker. And being able to select the target membership for individual files—a feature only provided by groups—can be very useful. For these reasons, you will find that groups are far more common in practice, and it is the option I recommend. You just have to live with the fact that if you move the files around on disk, you’ll have to manually update the Xcode project to match.

That said, it’s unfortunate that Xcode doesn’t offer better support for folder references. I wish I could use them more often, as I hate having to keep my project view in sync with the filesystem, but the IB problem keeps me away. And I almost never need groups, since my projects typically have only one target, and pretty much everything in my project folder gets bundled into the product. Maybe one day Apple will fix the IB bug and my wish can come true.

6 Responses to “Xcode Groups vs. Folder References”

  1. Alan Duncan says:

    There is a pseudo-workaround for the problem of folder-referenced images in IB.

    In IB if you specify the full path to the image in Image view:Attributes inspector:Image then the image will be loaded at runtime and you will not see the error you mentioned. The downside, of course, is that it breaks the preview of image in IB. (And the fact that you have to hard-code the path in IB.)

  2. kevinl says:

    This may or may not be of use to you, but if you were to use folder references and at the same time you don’t want to reference images with the full path, there’s a way you can still reference them using [UIImage imageNamed:@”just_this.png”]

    Under the build phases section in your target, add a new run script and add the following:

    find -L ${SRCROOT}// -type f -not -name “.*” -not -name “`basename ${INFOPLIST_FILE}`” | xargs -t -I {} cp {} ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/;

    this will add all your images in the folder reference into the actual .app build of your project. cheers

  3. Thomas says:

    Thanks for the comparison.
    Another thing to mention is that when using folder references Xcode seems to be unable to save any file settings, like encoding or syntax coloring for good. Close and reopen the project and the settings made are lost.
    Especially annoying since Xcode misinterprets all our source file encodings as MAC OS Roman, shredding some characters. (which is weird too since even simple TextEdit gets the encoding right)
    Has anyone found a solution for that? I’d be tremendously grateful for any advise on that one, cause it makes Xcode simply unusable for our project. Which is a pity.
    Best regards!

  4. Ray Scott says:

    Why don’t you simply import your folders containing your class files as folder references and import your folders containing resources such as images as groups, or am I missing something here? You can mix and match can’t you?

Leave a Reply