My Workflow Using Mainly Vim + Terminal to Create and Build XCode Project — Part I

Wasin Thonkaew
8 min readJul 12, 2015

--

First Thing First

Update: I was able to add new file via xcodeproj. See Part II.

This blog is in working-in-progress series of breaking free from IDE; Xcode. It's in almost state now but it's working just fine, and only use Xcode minimally. I will update this post again. Read on to learn more.

In a quest of breaking free from IDE, I was trying to only use only vim and terminal to do stuff out of the box. The reasons are as follows.

  • I have low to medium amount of memory for my MacBook Pro (4 GB didn’t seem to be enough for modern OS X update with lots of application opened at the same tim).
  • I want to break free from IDE, and be able to do things on pure editor and commands.
  • I want to finally get around to go deep and use vim as the main code editor.

I’m making game on iOS platform. I used both Xcode and AppCode with Cocos2dX to create the game.

My timeline starts with Xcode, then mainly AppCode, then finally vim + terminal but switch to Xcode to set project’s build setting from time to time, but only necessary (for now).

*In fact, I think you can use xcodeproj to manage project’s wide setting. But I didn’t have much time to do that now. In this article, I will tell you about my workflow and open source tools I use to code with minimal usage of Xcode; or say using Xcode only for project’s build setting.

Jump Right In

The following is the list of tool I use

  • iTerm2 — OS X terminal
  • tmux — terminal session management
  • slate — similar to xnomad but with lots of configuration and it works!
  • railscasts — terminal 256 color theme
  • ctrlp — file explorer within vim
  • xcodebuild — build tool for Xcode project
  • ios-deploy — debug iOS app on device, or manage iOS app/file directly
  • ag — super fast search tool alternative to ack

Tools I ever used but decided not to continue using it as it’s above my real need

All the tools I use above are open source and are hosted on github except only one which is xcodebuild which is bundled with Xcode’s dev tool or when you install Xcode.

Vim + Terminal

At a very first step, I choose iTerm2 over others. The one killing feature is cmd+D to split a new window pane in another different terminal session. This is especially very useful when I’m modifying the code, and need to do something separately. Just split the window, then I do things there. After I finish, then cmd+w to close and yeah, I’m done.

iTerm comes with a support of 256 color theme in which I decided to use railcasts as it catches my eyes the most and I really love its color palette. There are whole bunch of vim’s color themes at vimcolors.

From time to time, I always have a lots of terminal session opened. Some of them might be code related, or just pure hammering of commands to manage my project.

tmux could help organizing and remembering all those terminal sessions and save them into tmux-session in order to switch back again some time in the future without a lost of any of terminal sessions.

So it means, I might have several projects. Each one with lots of terminal session opened; lots of terminal windows. Having tmux helps organizing and remembering those will speed things up a bit. I start by creating a new tmux session via tmux new -s mysession. Then it goes into a new terminal session as part of tmux session. I can create a new tmux terminal session via my own key binding, or switch to any window, close one of them, or even restore the session after rebooting the system. See this cheat sheet to get start. Here is my .tmux.conf to bind the key to ctrl+\.

File explorer will help boost yet time lost in switching from vim to smashing out a command to find a file, then open it again. In fact, we do have options here.

  • :E as a command inside vim itself. This will open original file explorer. It has nice visual though. Select a file to open then hit enter or o to open the file. Hit v will open the file in a new split window vertically.
  • nerdtree I didn’t use it myself but you can find it here. Also read this too.
  • ctrlp I use this one. Inside vim, I can open the file searching up via ctrl+p then I can enter the file name right away. It searches matching the file very quick.

Above all else, I use ag to help me find a particular match over string output from another command I’ve chained, or use it to list of files that contain our search string. ag is quoted as a searching tool for programmer. It’s a replacement for ack tool with a very focus on speed. I can do the following thing with it

  • :Ag <searchtext> to list files that contain our search term inside vim
  • ag <searchtext> to list files that contain our search term

I would say it’s pretty much fast. My project has ~9000 files at maximum, and using ag doesn’t slow me down.

Window management

I use slate to snap opened application into left, right, up, or down of the screen. This is particularly very handy and useful if you ever use Windows system before. The one feature that OS X lacks of is this.

No need to use a mouse to carefully laid out and make the window cover all the area. slate comes with a lot (I say a lot!) of customization via configuration file. Personally, I need just a handful of them. Most of the time, I will be openning 2 window or 2 different application i.e. Chrome, and iTerm. I snap chrome to the left, and iTerm to the right. May be I snap chrome at full screen with iTerm snapping at the top with half height.

It’s up to what’s the best layout you need at the moment to give the best of producitivity and experience as much as possible. The thing is you can customize it with slate.

See my .slate for the configuration with key-binding that does the following

  • ctrl+cmd+left — Snap a window to the left occupying 60% of width and full height
  • ctrl+cmd+right — Snap a window to the right occupying 40% of width and full height
  • ctrl+cmd+1 — Snap a window to the top-right corner of the screen with 40% in width and 50% in height
  • ctrl+cmd+2 — Snap a window to the bottom-right corner of the screen with 40% in width and 50% in height
  • ctrl+option+1 — Make a window full screen. It’s like a canceling key.

Note xmonad for OS X didn’t really work. The very first time I’ve introduced to this kind of window management, I jump right into it in no time. But sadly, it didn’t work. It has a problem with key mapping in which it is interfered with the system’s key mapping.

Project Building Commands

Now we’re going into the real deal building iOS project from command line.

There're 2 points at the moment whenever I need to open Xcode to do things 1. Setting up project's setting 2. Creating a new source file I strongly believe we can do above with xcodeproj, but at this point I don't have time just yet.

Things we will do normally include

  • Building a project
  • Deploy a recently built (.app) to real device
  • (optional) Export Xcode’s build setting

First of all, refer to this as a reference if you need to technical note: Building from the Command Line with XCode.

It is a simple job to build a project if you only have only one project to build.

  • If you use a project + scheme
xcodebuild -project MyProject.xcodeproj -scheme MyScheme
  • If you use a workspace
xcodebuild -workspace MyWorkdSpace.xcworkspace -scheme MyScheme

You can supply the project or workspace parameter in path, but it is better to go direct to your project directory first then execute it.

In order to know the scheme, execute

xcodebuild -list -project MyProject.xcodeproj

Using xcconfig to Build Project

I prefer using xcconfig or Xcode configuration to build. This way, it offers a customization as it aligns with me to break free from the IDE itself.

If I need to build a project with different provision profile name, I can change it in the file without needing to open Xcode and set things up again. The flexibility is there.

Use

xcodebuild -project MyProject.xcodeproj -scheme MyScheme -configuration Debug -showBuildSettings

to show the current build setting for Debug configuration inside MyScheme. Thus we can write it into file by append > debug-build.xcconfig to former command.

I then build a project with the following command

xcodebuild -project MyProject.xcodeproj -xcconfig debug-build.xcconfigWarning When using xcconfig in building a project. A result xcconfig file needs to have first line removed. Also at the moment I cannot figure out why full export of build setting from with the command above cannot successfully build the project. I have to remove more or less than some of the build setting inside the file to make it work. But I cannot confirm which settings that effect just yet. To get the same effect as building without xcconfig file, just empty the xcconfig file and build the project with the command above.

But there’s a problem …

Problems for Sub-Project

The thing is that it would be a simple job if you only have a true single project. As xcodebuild won’t need to mess around with building your sub-project. Imagine if you have a sub-project as a dependency library that your main project needs. Then it needs to build that sub-project first before going back to build the main one.

The problem here is that in case of using xcconfig in building a project. I found a problem of xcodebuild cannot be able to resolve the current working directory to the correct one after it finishes the job of building a sub-project if those two project files are not in the same level of directory, and not use workspace.

This is important that I need to restructure my own project’s file and hierarchy. But fortunately, it’s not that hard.

So the first solution to use xcconfig to build a project is to restructure your Xcode project to lay out all those projects file (.xcodeproj) to be in the same level first.

Then you’re done building a project.

Deploy to iOS device

Use ios-deploy to upload a bundle (.app) which is a result from building a project to real device.

A notable commands that I use often is as follows.

  • ios-deploy -c to list the current connected devices
  • ios-deploy — debug — bundle /path/to/app/bundle.app to upload the app bundle to connected device (let it chooses from connected ones automatically), and start debugging with lldb immediately
  • ios-deploy — debug — bundle /path/to/app/bundle.app -i 46feafc8d86d42adac26bab589b46e26540568d1 to upload the app bundle to specified device id, and start debugging with lldb immediately

The path to bundle file can get from exporting a build setting in BUILT_PRODUCTS_DIR section.

See its github project for all other options.

Combine It All Together

For convenience as I will be interact with those commands very often, you know you make some changes and need to immediately debug it on real device as fast as possible.

I created a shell (bash) script, zhbuild, to manage our game.

Change the parameters as need.

Originally published at wasin.io.

--

--