Skip to content

Clody_iOS_Coding Convention

Seon Woo Kim edited this page Jun 28, 2024 · 1 revision

SwiftLint를 사용하지 않는다 , 대신 코드리뷰로 철저히 검사한다.

1️⃣ Class 이름

UpperCamelCase를 사용합니다.

  • ViewController, TableViewCell, CollectionViewCell 줄이지 않고 사용

2️⃣ Protocol 사용 시

extension으로 모두 빼기 : 하나의 extension에 프로토콜 하나씩

3️⃣ 변수 및 상수 이름

  • 알아볼 수 있는 네이밍을 사용해주세요!
  • lowerCamelCase를 사용합니다.

ex. nameList

4️⃣ 함수 이름

  • 알아볼 수 있는 네이밍 사용하기

  • 함수 이름에는 lowerCamelCase를 사용합니다.

  • Action 함수의 네이밍은 '주어 + 동사 + 목적어' 형태를 사용합니다.

    • Tap(눌렀다 뗌)*은 UIControlEvents의 .touchUpInside에 대응하고, *Press(누름)*는 .touchDown에 대응합니다.
    • will~은 특정 행위가 일어나기 직전이고, did~는 특정 행위가 일어난 직후입니다.
    • should~는 일반적으로 Bool을 반환하는 함수에 사용됩니다.
  • 좋은 예:

    func backButtonDidTap() {
      // ...
    }
  • 나쁜 예:

    func back() {
      // ...
    }
    
    func pressBack() {
      // ...
    }

5️⃣ 생명주기(Life Cycle)

생명주기 순서대로 작성해주세요

Untitled

class MovieRatingViewController: UITableViewController {

  // MARK: - View controller lifecycle methods

  override func viewDidLoad() {
    // ...
  }

  override func viewWillAppear(_ animated: Bool) {
    // ...
  }

  // MARK: - Movie rating manipulation methods

  @objc private func ratingStarWasTapped(_ sender: UIButton?) {
    // ...
  }

  @objc private func criticReviewWasTapped(_ sender: UIButton?) {
    // ...
  }
}

코드 레이아웃

줄바꿈

  • 함수 정의가 최대 길이를 초과하는 경우에는 아래와 같이 줄바꿈합니다. (P5)

    func collectionView(
      _ collectionView: UICollectionView,
      cellForItemAt indexPath: IndexPath
    ) -> UICollectionViewCell {
      // doSomething()
    }
    
    func animationController(
      forPresented presented: UIViewController,
      presenting: UIViewController,
      source: UIViewController
    ) -> UIViewControllerAnimatedTransitioning? {
      // doSomething()
    }
  • 함수를 호출하는 코드가 최대 길이를 초과하는 경우에는 파라미터 이름을 기준으로 줄바꿈합니다. (3개 이상 부터 줄바꿈하기!)

    let actionSheet = UIActionSheet(
      title: "정말 계정을 삭제하실 건가요?",
      delegate: self,
      cancelButtonTitle: "취소",
      destructiveButtonTitle: "삭제해주세요"
    )

    단, 파라미터에 클로저가 2개 이상 존재하는 경우에는 무조건 내려쓰기합니다.

    UIView.animate(
      withDuration: 0.25,
      animations: {
        // doSomething()
      },
      completion: { finished in
        // doSomething()
      }
    )
  • if let 구문이 길 경우에는 줄바꿈하고 한 칸 들여씁니다.

    if let user = self.veryLongFunctionNameWhichReturnsOptionalUser(),
       let name = user.veryLongFunctionNameWhichReturnsOptionalName(),
      user.gender == .female {
      // ...
    }
  • guard let 구문이 길 경우에는 줄바꿈하고 한 칸 들여씁니다. else는 guard와 같은 들여쓰기를 적용합니다.

    guard let user = self.veryLongFunctionNameWhichReturnsOptionalUser(),
          let name = user.veryLongFunctionNameWhichReturnsOptionalName(),
          user.gender == .female
    else {
      return
    }

빈 줄

  • 빈 줄에는 공백이 포함되지 않도록 합니다.

  • 모든 파일은 빈 줄로 끝나도록 합니다.

  • MARK 구문 위와 아래에는 공백이 필요합니다.

  • extension 전에 줄 바꿈은 하나만 합니다.

    // MARK: Layout
    
    override func layoutSubviews() {
      // doSomething()
    }
    
    // MARK: Actions
    
    override func menuButtonDidTap() {
      // doSomething()
    }

임포트

모듈 임포트는 알파벳 순으로 정렬합니다. 내장 프레임워크를 먼저 임포트하고, 빈 줄로 구분하여 서드파티 프레임워크를 임포트합니다.

import UIKit

import SwiftyColor
import SwiftyImage
import Then
import URLNavigator
import UIKit

import SnapKit

final class MainView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setUI()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setUI() {
        setHierarchy()
        setConstraints()
    }

    func setHierarchy() {
        self.addSubview(scrollView)
    }

    func setConstraints() {
        view.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
    }
		
		func configureImageView() {
				view.backgroundColor = .white
		 }
}

https://github.com/StyleShare/swift-style-guide