Search code examples
gitxcode4git-submodules

Xcode 4 workspace with two interdependent projects: should I also use git submodule?


I'm working on an iOS app and have broken the codebase into two separate projects: a client library for a web service, and an app project that depends on the client library.

Both projects have been added to a single Xcode workspace with the dependency appropriately declared.

Each project has its own git repository. Currently I have the two projects checked out to two separate directories, and I manage the two git repositories independently of each other. The only place where the dependency between these two pieces of code is currently defined is in the app's Xcode project.

However, I'm wondering whether I should add the client library git repository as a git submodule of the app's repository. This feels right conceptually but I haven't used git submodules before and I'm wondering if there are any gotchas with using this approach with Xcode?

(I can find plenty of blog posts on how to use Xcode workspaces to manage inter-project dependencies like this, and elsewhere plenty of documentation on git submodules, but I can't find a single account of a tried and tested workflow for using both together. If you know of one, please post a link!)


Solution

  • I've been involved in projects that have done this before, all using the following layout:

     * app-workspace
      * App.workspace
      * library [submodule]
       * Library.xcodeproj
       * library sources
      * app [submodule]
       * App.xcodeproj
       * app sources
    

    So the workspace knows about the projects and the build schemes. The workspace's git repository knows about the submodules containing the projects.

    In practice it's a lot of effort to keep the submodule definitions at the top level up to date, so we've usually ended up working on the submodules' master branches. Committing specific versions to the workspace's submodules happens when important changes are added: not too infrequently if the CI system builds from the top-level project.

    Of course, for the unit tests you can point the CI at each submodule independently, it's only integration tests that will require the whole workspace. An important step to remember here - and one that I occasionally mess up - is that you should only update the submodule definition to a particular commit after you've pushed that commit to the shared origin of the CI and developer repos. If you forget this, you risk the checkout breaking for other people when the parent project refers to a commit of the submodule that they don't have.

    The place where you potentially get issues with interacting with Xcode is in defining your build schemes. The approach I've most recently taken is to use the scheme editor to define the schemes I want to use as being shared (instead of per-user), and defined in the workspace at the top level instead of in the projects in the submodules. With that done, and those scheme definitions committed to git, turn off automatic scheme generation. Now all of your developers and the CI system all agree on how to build your product.