当記事は、Colorful Board Advent Calendar 2016の18日目の記事になります。
今回は Swift のコーディングをする上でのガイドラインになります。
現プロジェクトの環境に合わせてガイドラインを設定しているので、Swift のバージョンは 2.3 を前提としています。
(また、現時点で定義できていないガイドラインもあるので、決まり次第随時更新していきたいと思います)
主に参考にしているガイドラインは以下になります。
- Swift.org - API Design Guidelines
- github/swift-style-guide
- SmartTechVentures/swift-style-guide
- eure/swift-style-guide
- Swiftコーディング規約@Wantedly - Qiita
ホワイトスペース
- インデントは スペース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)