XcodeGenでiOSチーム開発でのストレスを軽減する

概要

チームで iOS 開発をする際 xcodeproj ファイルはコンフリクトが発生しやすい状況となります。
XCodeGen というツールを用いて xcodeproj ファイルのコンフリクトと解消にかかる手間暇を回避していきます。

動機

xcodeproj ファイルは、 プロジェクトのファイル構成や設定など様々な情報を保持しているファイルです。プロジェクトにファイルを加えただけで変更されるので、 差分が入りやすくチーム開発の際にコンフリクトしやすくなっています。加えて、 xcodeprojファイルは独自の構造を持っているため、 中身を読んで理解するのは容易ではありません。
これらの性質のため、 iOS のチーム開発にて xcodeproj ファイルはコンフリクトしやすい上に修正が容易ではないので、 コンフリクト解消には手間暇がかかることもあり何度も続くとストレスになりえます。

XcodeGen は、 yaml 形式の設定ファイルから xcodeproj ファイルを生成するので、 xcodeproj ファイルを git で管理する必要がなくなり、 これらの問題を回避することができます。

導入

XcodeGen のインストール

HomeBrewを用いてインストールします。 (HomeBrewのインストールについてはここでは割愛します)

$ brew install xcodegen

設定ファイルを準備する

プロジェクトルートに project.yml を準備して中身は以下のようにします。

name: YourProjectName
targets:
  HogeProject:
    type: application
    platform: iOS
    # sourcesでディレクトリ構造を固定できます。該当するディレクトリがないとエラーとなるので先に作っておきます。
    sources: Sources

シンプルにビルドターゲットと役割・ディレクトリ構造だけ設定しました。

$ xcodegen をプロジェクトルートで実行することによって、 project.yml に対応する xcodeproj ファイルが生成されます

Configration と Scheme の設定

普段 Xcode の GUI 上で設定することの多い Configration と Scheme の設定も project.yml で設定しておく必要があります。

configs:
  Debug: debug
  Release: release
schemes:
  HogeProjectDebug:
    build:
      targets:
        HogeProject: all
        HogeProjectTests: [test]
  HogeProjectRelease:
    build:
      targets:
        HogeProject: all
        HogeProjectTests: [test]
    run:
      config: Release
    test:
      config: Release
    profile:
      config: Release
    analyze:
      config: Release
    archive:
      config: Release

ユニットテストが必要なケース

ユニットテストが必要な場合, テスト用 Targets の追加と Scheme の設定をします。

targets:
  HogeProject:
    type: application
    platform: iOS
    sources: Sources
  # 追加
  HogeProjectTests:
    type: 'bundle.unit-test'
    platform: iOS
    sources: Tests
    dependencies:
      - target: HogeProject
schemes:
  HogeProjectDebug:
    build:
      targets:
        HogeProject: all
        HogeProjectTests: [test]
    # 追加
    test:
      config: Debug
      targets:
        - HogeProjectTests

細かい設定が必要なケース

場合によっては Build Setting や Build Rules なども設定しなければいけないケースも存在すると思います。これらも project.yml 上に書く必要があります。 ここで厄介なのが、 Xcode で表示されるプロパティ・値と xcodeproj ファイルでの表記( project.yml で使う文字列) が必ずしも一致しないことです。 xcodeproj ファイルをエディタで開き、 それっぽいプロパティ名で検索するか、 プロパティの変更前後で git diff <xcodeproj ファイルのパス> を実行してプロパティ名を追いかけて行くのが最短だと思います。

project.yml に記載する一例だけ示します (例ではターゲットOSバージョンを指定しています)。

settings:
  configs:
    Debug:
      IPHONEOS_DEPLOYMENT_TARGET: 9.0
    Release:
      IPHONEOS_DEPLOYMENT_TARGET: 9.0

運用

project.yml から xcodeproj ファイルが生成可能なので xcodeproj ファイルは git 管理の対象から外します。 チームメンバー各自がブランチ切り替え時などに $ xcodegen を実行して xcodeproj ファイルを生成します。
なお CocoaPodsを使っている場合には, xcodegenproj ファイル生成後に $ bundle exec pod install など実行して xcworkspace ファイルを再生成する必要があります。

まとめ

XcodeGenを用いることによって差分・コンフリクトが発生しやすい上に、 その対応が面倒な xcodeproj ファイルを自分のPC上で生成することができ、 コンフリクト解消にかかる手間暇を省くことができました。

すでにお気付きの方もいらっしゃるかもしれませんが、 XcodeGenの初回導入に少々時間やリソースが必要です (何も知らないところから XCodeGen を導入しましたが1, 2営業日ほどかかりました)。 短期や小規模な開発だと、 この初期コストに見合わないかもしれません。 プロジェクトの規模感を見積もりながら必要に応じて XcodeGenを用いると良さそうです。

より詳細な内容は XcodeGenを用いてxcodeprojから卒業する で読むことができます。

参考文献