Skip to content

팀 Swift Style Guide

SeungHwan Lee edited this page Jan 26, 2022 · 3 revisions

General한 규칙들

  • 최소한의 import, 모듈 import시 알파벳순으로 import
  • 최대 가로 길이는 100자 제한, 글자수 초과시 개행
  • 들여쓰기: Space 4개
  • : (콜론) 사용시 오른쪽에만 공백 (삼항연산자에서의 콜론은 예외, 삼항 연산자는 콜론 앞 뒤로 공백)
    // Good
    var nameAgeMap: [String: Int] = []
    
    // Bad
    var nameAgeMap: [String:Int] = []
    var nameAgeMap: [String : Int] = []
  • +, -, *, / 등 연산자 앞뒤에는 가독성을 위해 앞뒤로 공백 추가
  • , (콤마) 사용시, 콤마 뒤에는 공백 추가
    // Good
    let numbers = [1, 2, 3]
    
    // Bad
    let numbers = [1,2,3]
    let numbers = [1 ,2 ,3]
    let numbers = [1 , 2 , 3]
  • 불필요한 괄호는 사용x 괄호는 필요할 때만 사용
  • 2개 이상의 데이터를 반환할 때는 튜플보다는 struct를 고려, 튜플 사용시 각각의 필드에 이름을 붙이는걸 권장
  • 상속이 발생하지 않는 클래스는 final 키워드로 선언
  • 프로토콜을 채택할 때는 extension을 통해 관련된 매소드를 작성
  • Switch문 사용시 default 사용을 지양 (의도적으로 case 지정)

네이밍

  • 파일의 경우 단일 타입일시, 파일명은 타입명과 같게 명명, 만약 프로토콜 준수로 기존 타입을 확장하는 경우라면 타입명 + 프로토콜명의 조합으로 명명
  • lowerCamelCase: 함수, 메소드, 변수, 상수 등에 사용
  • UpperCamelCase: 클래스, 구조체, 열거형, Extension 등에 사용
  • 약어로 시작할 경우 소문자로 표기하고 그 외의경우 대문자로 표기
    // Good
    let userID: Int?
    let html: String?
    let websiteURL: URL?
    let urlString: String?
    
    // Bad
    let userId: Int?
    let HTML: String?
    let websiteUrl: NSURL?
    let URLString: String?
  • 함수의 경우 이름 앞에 get 사용 지양
    // Good
    func name(for user: User) -> String?
    
    // Bad
    func getName(for user: User) -> String?
  • Action 함수의 네이밍은 wasTapped 사용 (From Google Style Guide)
    @objc private func ratingStarWasTapped(_ sender: UIButton?) {
      // ..
    }

코드 레이아웃

  • delegate 매소드 정의시, 첫 번째 매개변수는 delegate source 이름이어야 한다.
    // Good
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)
    func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool
    
    // Bad
    func didSelectName(namePicker: NamePickerViewController, name: String)
    func namePickerShouldReload() -> Bool
  • 리턴 타입이 없는 경우 클로저는 () 대신 Void 사용, 함수는 생략
    // Good
    func updateConstraintns() {
      // ..
    }
    
    typealias CompletionHandler = (result) -> Void
    
    // Bad
    func updateConstraintns() -> () {
      // ..
    }
    
    typealias CompletionHandler = (result) -> ()
  • 한 줄 클로저의 경우 괄호 양쪽에 공백 추가
    // Good
    let squares = [1, 2, 3].map { $0 * $0 }
    
    // Bad
    let squares = [1, 2, 3].map {$0 * $0}
  • 제네릭의 경우 관계나 역할을 나타낼수 있는 의미있는 이름으로, upper camel case로 나타내야 한다. 단 관계나 역할을 나타낼수 없는 경우 T, U, V 사용 가능
    // Good
    struct Stack<Element> { ... }
    func write<Target: OutputStream>(to target: inout Target)
    func swap<T>(_ a: inout T, _ b: inout T)
    
    // Bad
    struct Stack<T> { ... }
    func write<target: OutputStream>(to target: inout target)
    func swap<Thing>(_ a: inout Thing, _ b: inout Thing)
  • Array Dictionary<T: U> 보다는 [T], [T: U] 사용
    // Good
    var messages: [String]?
    var names: [Int: String]?
    
    // Bad
    var messages: Array<String>
    var names: Dictionary<Int, String>?
  • 타입 추론이 가능하면 더 간결한 코드를 위해 타입은 생략
    // Good
    let selector = #selector(viewDidLoad)
    view.backgroundColor = .red
    let toView = context.view(forKey: .to)
    let view = UIView(frame: .zero)
    
    // Bad
    let selector = #selector(ViewController.viewDidLoad)
    view.backgroundColor = UIColor.red
    let toView = context.view(forKey: UITransitionContextViewKey.to)
    let view = UIView(frame: CGRect.zero)
  • 함수 정의가 최대 길이를 초과하는 경우 아래와 같이 개행
    func collectionView(
      _ collectionView: UICollectionView,
      cellForItemAt indexPath: IndexPath
    ) -> UICollectionViewCell {
      // ..
    }
    
    func animationController(
      forPresented presented: UIViewController,
      presenting: UIViewController,
      source: UIViewController
    ) -> UIViewControllerAnimatedTransitioning? {
      // ..
    }
  • 함수 호출 코드가 최대 길이를 초과하는 경우, 파라미터이름을 기준으로 개행
    let actionSheet = UIActionSheet(
      title: "정말 계정을 삭제하실 건가요?",
      delegate: self,
      cancelButtonTitle: "취소",
      destructiveButtonTitle: "삭제해주세요"
    )
  • 파라미터에 클로저가 2개 이상일 경우 내려쓰기를 통해 가독성을 높인다.
    UIView.animate(
      withDuration: 0.25,
      animations: {
        // ..
      },
      completion: { finished in
        // ..
      }
    )

주석의 사용

  • // MARK: 연관된 코드 그룹핑, 해당 그룹에 대한 설명 명시
  • // TODO: 추가적으로 할 일 명시
  • // FIXME: 수정해야할 것 명시

참고

Clone this wiki locally