Help us understand the problem. What is going on with this article?

iOSアプリ開発時の実ファイルの配置ベストプラクティス

More than 5 years have passed since last update.

Androidアプリ開発時に使うEclipseなどとは違い、Xcode上のファイルグループ分けと実ファイルの物理構成はリンクしているわけではないので、実ファイルをどのように配置していくのかはプロジェクト初期にメンバーで都度決めていると思います。

自分がいつもやっているのは実ファイルをMVCに分類し、Classesディレクトリの下にMVCディレクトリを作りそこに配置していくことです。

例としてクラスAModel,BModel,AControllerとリソースであるstoryboardやxibがある場合は次のようにしています。

SampleProject/Classes/Models/AModel.h
SampleProject/Classes/Models/AModel.m
SampleProject/Classes/Models/BModel.h
SampleProject/Classes/Models/BModel.m
SampleProject/Classes/Controllers/AController.h
SampleProject/Classes/Controllers/AController.m
SampleProject/Classes/Views/Main.storyboard
SampleProject/Classes/Views/CustumCell.xib
SampleProject/Classes/Views/CustumCell.h
SampleProject/Classes/Views/CustumCell.m

なぜClassesディレクトリを使うのか

現在のXcode5系のテンプレートプロジェクトのまま作ってしまうとClassesディレクトリがなく、plistやpcxファイルと同じディレクトリに全てのコードが配置されるとプロジェクトの見通しが悪く感じてしまいます。また、Xcode3系のときはClassesディレクトリが自動で作成されていた事があり、そのClassesという名前をそのまま使っています。

なぜユースケースごとに分けないのか

複数のユースケースがある場合、どのユースケースのディレクトリに格納すべきか迷うのを避けるためです。webアプリであれば画面ごとにControllerを分けることも多いと思いますが、iOSアプリ開発ではViewControllerは画面に依存しているというよりもViewとModelに依存しており、さらにコンテナ機能によって使い回しがしやすいために画面ごとに分けるのは後々余計な頭を使ってしまいます。

なぜMVC以下は深く分けないのか

さきほどの例ではAModel.hとBModel.hは実ファイルの構成上同じModels階層にいますが、この階層を深く分けたくなると思います。例を示すと次のようになります。

SampleProject/Classes/Models/A/AModel.h
SampleProject/Classes/Models/A/AModel.m
SampleProject/Classes/Models/B/BModel.h
SampleProject/Classes/Models/B/BModel.m

これで見通しの良さは向上するのですが、開発中、Xcode上でAModelのグループ名Aを変更したくなるときがあるでしょう。そのとき、グループ名を変えた上でディレクトリ名を同じように変えたくなりますよね。しかし、Xcode上で実ディレクトリ名を変えることはできないため、Xcode上での操作+GUI or CUIでのコマンド操作が必要になりどうしても開発のリズムを崩しリファクタリングが億劫になり良くありません(特にgit/svnを使っていた場合は面倒な感じを受けます)。

したがって、リファクタリングでMVC間をまたがるということはないとして、実ファイルはMVCには分けるがそれ以上は分類しないということで妥協します。Xcode上のグループは分かりやすくMVC以下も深く分けていくのが良いと思います。

MVCに分類できないのはどうするの?

よくあるパターンとしてUtilitesとかCategoriesとかでしょうかね。ViewとControllerに分類できないならModelでいいとは思いますが、開発チーム内で話しあって決めたいところです。

画像やサウンドなどリソースの配置はどうするの?

Xcode5からはAsset Catalogが導入され、画像のリソースの配置や命名についてはほとんど気にしなくなりましたが、Asset Catalogを使えない場合は次のような制約が適切です。

  • リソースは一つのディレクトリに平たく置かず物理ディレクトリを分ける
  • Resourcesディレクトリを作りその下にimagesとsoundsとする
  • imagesディレクトリの下にbutton、iconsと構成していく
  • ディレクトリ構成とグループ構成を一致させる

ソースコードの場合はリファクタリングすることが多いためディレクトリ構成を深くしないのですが、画像などのリソースファイルはディレクトリやグループ構成をリファクタリングしたくなることが少ないため、整理しやすさを重視してディレクトリを作成しグループ構成と合わせます。

自分の経験から次のような理由があります

  • デザイナから提供される素材が未整理で一つのディレクトリにまとめて送ってくるという事はないのでその構成を維持してあげる
    • 素材を貰う前の自作したダミー構成は捨てる
  • Xcodeを起動しなくてもディレクトリでわけてあれば他のプロジェクトの画像が把握しやすい
    • 再利用するときに他の開発メンバーやデザイナも画像を見つけやすい

画像をimagesディレクトリに置くこともメリットがあるので、開発チーム内での認識合わせによると思います。

ちなみにAsset Catalog上のAsset名は実ファイルの画像名と違ってもいいので、デザイナが送ってきたファイル名が規約に沿っていないなどであっても指摘したりファイル名を変更する必要がなくなり便利ですね。

参考

意図が同じかどうかは分かりませんが、はてなインターン2013の構成も自分と同じような構成だったので参考にリンクしておきます

https://github.com/hatena/ios-Intern-Bookmark-2013/tree/master/InternBookmark/Classes

その他

  • Xcode上でも物理ファイル構成の連携できてなかったっけ?
  • 他にもいい方法があれば教えて下さい
yimajo
株式会社キュリオシティソフトウェアの代表です。iOSアプリを作っています。最近はCombine frameworkガイドブック / RxSwift研究読本などを書いてます。
https://swift.booth.pm/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away