iDev recipes is a series of short articles that present ways of dealing with common problems while developing apps for Apple devices.
One of the most frustrating things about Xcode is that project layout does not have to reflect directory structure. It seems like a powerful feature at first, but soon you find yourself fighting with directory bindings every time you add a new source file.
In the past I have tried two approaches to circumvent the problem:
- Creating blank files on a filesystem with
- Using sticky notes to remind myself that I always have to bind a new group to a directory first.
Both of them require additional hassle and fall short when it comes to refactoring. Does it mean that we are stuck to have all the projects look like this?
Fortunately, there is a tool called synx which can align directory structure with project layout using a single terminal command. It also sorts files in groups, so you are guaranteed that both Xcode and Finder will look the same. Examine result of running
synx Project.xcodeproj on a project above:
It is so much tidier now. Could it get any better? The problem is that running a terminal command every once in a while to fix a project layout is not convenient. But do not worry. Provided that you use git repository for your project, you can configure it to tidy up the project every time you commit anything. Say goodbye to manual directory juggling!
Since synx is written in Ruby, the first step is to install proper Ruby interpreter. You could use OS X built-in, but it is always a better idea to go with the latest software. To make Ruby version management easier, we will use rbenv for the task. To install rbenv using Homebrew run following commands:
brew update brew install rbenv # Replace .bash_profile with .zshrc if you are using ZSH. echo 'eval "$(rbenv init -)"' >> ~/.bash_profile source ~/.bash_profile
Having rbenv installed properly, it is time to install the latest version of Ruby interpreter (make sure to replace
2.3.1 with the output version):
rbenv install `rbenv install -l | grep -v - | tail -1` # Output: # Installing ruby-2.3.1... # Installed ruby-2.3.1 to /Users/kuba/.rbenv/versions/2.3.1 rbenv rehash rbenv global 2.3.1
Installing synx is as easy as running one Terminal command:
gem install synx
Configuring synx pre-commit hook
Git has a way to fire off custom scripts when certain important actions occur.
Quote from Git Hooks documentation.
To make git fire synx before every commit do the following:
Navigate to hooks directory
Rename pre-commit.sample file to pre-commit
mv pre-commit.sample pre-commit.
Replace pre-commit file contents with:
#!/bin/sh synx <project_name>.xcodeproj git add <project name>.xcodeproj
Make pre-commit file executable
chmod +x pre-commit.
To confirm that everything is working as expected, make any changes to your sources and try to commit them. You should see the output from synx application before commit message input prompt:
git add -A git commit
Additionally, you can add
-q flag to synx in pre-commit to silence all output. However, since synx operates on a project file directly you should always examine error logs in case something goes wrong.
The final step
Having completed configuring a synx hook, it is time for one final step. Which is to write some high quality code, commit it and admire how the computer automatically keeps your Xcode project tidy.