こんにちは。iOSエンジニアの遠藤です。 今回はiOSチームでの実装規約について紹介したいと思います。
Swiftのコーディングについてだけではなく、実装する上での細かい約束事をまとめました。 参考になれば幸いです。
実装規約について
VASILYでのiOSアプリ実装規約はこちらからご参照ください。
実装規約とは?
普段多く見る規約はコーディング規約だと思います。 しかしVASILYではコーディングだけではなく、Interface Builder上でのViewの階層やコードの並び順などコード自体の書き方だけではなくチームで開発・実装をするうえで気をつけることについても触れています。 そのため、コーディング規約ではなく実装規約としています。
実装規約の目的
実装規約にも書いてありますが、本規約の目的は以下の3つです。
- コードの統一
- パフォーマンスの向上
- メンテナンス性の向上
複数人で開発をしていると、スペースの空け方1つをとっても個人によって違います。 コードに統一性がないと様々な書き方が溢れてしまい、開発する上でもメンテナンスする上でも大変になってしまいます。 そのため、コードの統一性をとても重要視しています。 また、規約を守ることによりPRでの書き方の指摘も減り、本質的なレビューに注力することができるのも大きなメリットです。
誰が読んでも分かりやすいコードを書くために、思いやりのあるプログラミングが大事です。
実装規約の内容
短いguard節は一行で書く
guard節のelseになった場合の処理は何もせずにreturn
することが多いので、一行で書くようにしています。
コードの行数が短くなってスッキリとするのでコードの読み手に優しくなります。
VASILYでは一行100字を目安にしています。
例)
// Bad guard array.isEmpty else { return } // Bad // Good guard array.isEmpty else { return }
MARK, TODO, FIXMEを積極的に使用する
ファンクションメニューにコメントが表示されるようになり、コードの管理がしやすくなります。
VASILYでは以下のような意味合いで使い分けています。
キーワード | 内容 |
---|---|
MARK | 処理のまとまり |
TODO | タスク |
FIXME | 動作はしているが書き直したいコード |
処理のまとまりや、タスクなどが明示的に書いてあることで開発するうえでもメンテナンスをする上でもコードやタスクの把握がしやすくなるためチーム全体に優しくなります。
例)
final class TableViewController: UIViewController { // FIXME: スペースの実装が複雑なのでcollectionViewに置き換えてUICollectionViewFlowLayoutで実装する @IBOutlet private weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() setupTableView() } // MARK: - View private func setupTableView() { tableView.delegate = self ... // TODO: あとでtableHeaderViewの設定をする } } // MARK: - UITableViewDataSource extension TableViewController: UITableViewDataSource { ... }
Interface BuilderのDocument Outlineの順番
Interface BuilderのDocument Outlineの階層は見た目の階層と合わせるようにしています。 ぱっとみてどのパーツと紐付いているのかが分かりやすくなります。
例) // Bad
// Good
実装規約を守るために
実装規約を守るには普段から意識してコードを書くことが大切です。 しかし、意識をしていたとしても規約を完璧に守るのは難しいです。 ですから、iOSチームでは以下の仕組みを利用して規約を守っています。
- SwiftLint
- コードスニペット
- .clrファイルを共有する
SwiftLint
実装規約を意識して書いていたとしても、うっかり余計なスペースが入ってしまうことはあります。 そのちょっとしたミスを見つけるためにビルドするたびにSwiftLintを使用してコードをリントをかけてチェックしています。 ビルド時にミスを見つけることができるので、PRで書き方の指摘を減らすことができます。
SwiftLint については以下を参照してください。
https://github.com/realm/SwiftLint
コードスニペットの活用
UITableViewDataSource,UITableViewDelegateはアプリ開発で頻繁に実装するコードなので、コードスニペットを使用しています。 そうすることでコードの並び順を気にする必要がなくなります。
スニペット例
// MARK: - UITableViewDataSource extension <#viewController#> { override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return <#code#> } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { <#code#> } } // MARK: - UITableViewDelegate extension <#viewController#> { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { <#code#> } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { <#code#> } }
.clrファイルを共有する
Interface Builderで使用する色を.clrファイルにまとめてチームで共有しています。 そうすることで、微妙な色の数値間違いの発生を防ぐことができます。 また、設定したい色を簡単に選ぶことができるのも大きなメリットです。
さいごに
iOSアプリの実装規約について紹介しました。 実装規約はチームで開発をしやすくするためのものなので、モダンな記法、分かりやすい書き方があれば随時更新していきます。 ちょっとした手間で優しさと思いやりある開発をしていきたいと思います。
VASILYでは優しさあふれるコードを書きたいエンジニアを募集しています。 少しでも興味がある方は以下のリンク先をご覧ください。