Posted at

iOS コーディングガイドライン

More than 1 year has passed since last update.

当記事は、Colorful Board Advent Calendar 2016の18日目の記事になります。

今回は Swift のコーディングをする上でのガイドラインになります。

現プロジェクトの環境に合わせてガイドラインを設定しているので、Swift のバージョンは 2.3 を前提としています。

(また、現時点で定義できていないガイドラインもあるので、決まり次第随時更新していきたいと思います)

主に参考にしているガイドラインは以下になります。


ホワイトスペース


  • インデントは スペース4つ でインデント。タブは使用しない。

  • ブラケットの前後に半角スペースを入れる。

  • コンマの後ろに半角スペースを入れる。

  • メソッドの戻り値の -> の前後に半角スペースを入れる。

  • 演算子の前後に半角スペースを入れる。



  • 1行は、 80文字以内 にするようにする。折り返す際は関連する行のインデントに合わせる。(何文字が妥当かはプロジェクト毎に決めてください)

  • ブロックの間は1行空ける。

import UIKit

final class SampleViewController: UIViewController {

override func viewDidLoad() {}

override func viewWillAppear(animated: Bool) {}
}


セミコロン

行末のセミコロンは使用しない。


マジック[ナンバー|ワード]の禁止

記述した本人にしか意味が分からない数値や文字列の利用を避け、他の人にもわかりやすい命名や記述を心がける。

Preferred

let viewRectPadding = 10.0

let viewRect = CGRect(
x: viewRectPadding,
y: viewRectPadding,
width: view.frame.width - (viewRectPadding * 2),
height: view.frame.height - (viewRectPadding * 2)
)

Not Preferred

let viewRect = CGRect(

x: 10.0,
y: 10.0,
width: view.frame.width - 10.0,
height: view.frame.height - 10.0
)


メソッド分割

viewDidLoad 等のメソッド内で設定等を直接記述せずに専用のメソッドを用意する。

Preferred

override func viewDidLoad() {

super.viewDidLoad()

configureAppearance()
configureTableView()
}

func configureAppearance() {
backgroundColor = .whiteColor()
}

func configureTableView() {
let contentInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 20.0, right: 0.0)
tableView.backgroundColor = .blackColor()
tableView.contentInset = contentInset
}

Not Preferred

override func viewDidLoad() {

super.viewDidLoad()

backgroundColor = .whiteColor()
let contentInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 20.0, right: 0.0)
tableView.backgroundColor = .blackColor()
tableView.contentInset = contentInset
}


命名規則


クラス・構造体・列挙体・プロトコル・ジェネリクスの型パラメータ

プレフィックスなしの UpperCamelCase とする

class SampleClass {

}

enum SampleEnum {
}

struct SampleStruct {
}

protocol SampleProtocol {
}


変数・メソッド・enumのcase

lowerCamelCase とする

let sample: String = ""

func sample() {}

enum Sample {
case hoge
}


UIKitを継承する時の命名

class SampleViewController: UIViewController {

}

class SampleButton: UIButton {
}

class SampleCell: UITableViewCell {
}


変数, 定数定義


変数, 定数共通

型を省略して、特定の場合だけ型を記述するよりも、一律記述するほうが迷わなくてすむため、型は省略せずに記述する

また、基本 let で宣言し、変更される可能性があるときのみ var で宣言する。

Preferred

let text: String = "Hoge Fuga"

let frame: CGRect = .zero

let device: UIDevice = UIDevice.currentDevice()
let device: UIDevice = .currentDevice() // こういう書き方も可

Not Preferred

let text = "Hoge Fuga"

let frame = CGRectZero

let device = UIDevice.currentDevice()


変数定義

空の配列、連想配列も上記と同様に型を記述する。

Preferred

var elements: [Int] = []

var namesOfIntegers: [Int: String] = []

Not Preferred

var elements = [Int]()

var namesOfIntegers = [Int: String]()


定数定義

グローバルスコープ、クラススコープでの定数はprefixに小文字の k を記述する。

let kAnimationDuration = 0.3


final

定義をオーバーライドしないときは final を宣言する。

final class SampleViewController: UIViewController {

}

class Button: UIButton {
}

final class PrimaryButton: Button {
}


演算子


インクリメント、デクリメント

Swift 3.0 への移行を想定して、使用しない。


ファイル内の宣言順

プライベートメソッドやプロトコル等の実装はファイル内に extension を用いて記述する。

なお、宣言する順序は以下の通りとする。

import UIKit

// MARK: - Selector

private extension Selector {
}

// MARK: - Protocol

protocol SampleViewControllerDelegate {
}

// MARK: Class

final class SampleViewController: UIViewController {

override func viewDidLoad() {}
}

// MARK: IBActions methods

extension SampleViewController {

@IBAction func onCancelButton(sender: UIButton) {}
}

// MARK: UITextFieldDelegate methods

extension SampleViewController: UITextFieldDelegate {
}

// MARK: Private methods

private extension SampleViewController {
}


リテラル

ソースコード内で極力リテラルを記述しない。

また、そのように記述できるような実装を心がける。

(定数を宣言する専用のファイル内にまとめる. 例: Constants.swift等)

Preferred

view.backgroundColor = .backgroundColor(.black)

let params: ApiParameters = ApiParameters().set(.Limit(10))
SampleApi.configure(.Get, params).request()
// => GET /sample?limit=10

Not Preferred

view.backgroundColor = UIColor(hex: 0xf1f1f1)

SampleApi.request("GET", {limit: 10})


IBOutlet

Interface Builder で storyboard や xib とリンクした変数は必要ない限りは private にする。

Preferred

@IBOutlet private weak var view: UIView!

Not Preferred

@IBOutlet weak var view: UIView!


コメント

//

// Filename.swift
// Project Name
//
// Created by XXXX XXXX on YYYY/MM/DD.
// Copyright © YYYY Organization Name. All rights reserved.
//

import UIKit

/**
* SampleViewの説明
*/

final class SampleView: UIView {

override func awakeFromNib() {
super.awakeFromNib()

foo("bar")
}
}

// MARK: Private methods

private extension SampleView {

/**
* foo()の説明
*
* - parameter bar: barの説明
*/

func foo(bar: String) {}
}


参考


不要なコメントは残さない

ソースファイル内にメモ用途の記述は残さずに Github の Issues やその他チケット等に記載する。


その他


  • ベータ版や実績のないライブラリや、UIライブラリ等は検討してから導入する。

  • デバッグ用の print() は残さない。

  • ビルド時の警告は放置しない。

  • Gitのコミットメッセージは、ネイティブ言語を使って丁寧に記載する。 (良くない例: modify, fix bug)