Skip to content

Code Convention

Rey edited this page Jul 27, 2022 · 13 revisions

μ½”λ“œ λ ˆμ΄μ•„μ›ƒ

λ“€μ—¬μ“°κΈ° 및 띄어쓰기

  • λ“€μ—¬μ“°κΈ°μ—λŠ” νƒ­(tab)을 μ‚¬μš©ν•©λ‹ˆλ‹€.

  • 콜둠(:)을 μ“Έ λ•Œμ—λŠ” 콜둠의 였λ₯Έμͺ½μ—λ§Œ 곡백을 λ‘‘λ‹ˆλ‹€.

    let names: [String: String]?

μ€„λ°”κΏˆ

  • ν•¨μˆ˜ μ •μ˜κ°€ μ΅œλŒ€ 길이λ₯Ό μ΄ˆκ³Όν•˜λŠ” κ²½μš°μ—λŠ” μ•„λž˜μ™€ 같이 μ€„λ°”κΏˆν•©λ‹ˆλ‹€.

    func collectionView(
      _ collectionView: UICollectionView,
      cellForItemAt indexPath: IndexPath
    ) -> UICollectionViewCell {
      // doSomething()
    }
    
    func animationController(
      forPresented presented: UIViewController,
      presenting: UIViewController,
      source: UIViewController
    ) -> UIViewControllerAnimatedTransitioning? {
      // doSomething()
    }
  • ν•¨μˆ˜ 호좜 μ½”λ“œκ°€ μ΅œλŒ€ 길이λ₯Ό μ΄ˆκ³Όν•˜λŠ” κ²½μš°μ—λŠ” νŒŒλΌλ―Έν„° 이름을 κΈ°μ€€μœΌλ‘œ μ€„λ°”κΏˆν•©λ‹ˆλ‹€.

    let actionSheet = UIActionSheet(
      title: "정말 계정을 μ‚­μ œν•˜μ‹€ κ±΄κ°€μš”?",
      delegate: self,
      cancelButtonTitle: "μ·¨μ†Œ",
      destructiveButtonTitle: "μ‚­μ œν•΄μ£Όμ„Έμš”"
    )
  • 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
    }
  • μΈμžκ°€ μ—†λŠ” ν•¨μˆ˜μ˜ 연속적 ν˜ΈμΆœμ€ κ°œν–‰μ„ ν•˜μ§€ μ•ŠλŠ”λ‹€.

    someThing.firstFunc().secondFunc().End()

    단, SwiftUI View의 ModifierλŠ” μ˜ˆμ™Έλ₯Ό λ‘”λ‹€.

      ``` swift
      Text("This is Text")
          .bold()
          .padding()
      ```
    
  • μΈμžκ°€ μžˆλŠ” ν•¨μˆ˜μ˜ 호좜과 ν›„ν–‰ ν΄λ‘œμ €κ°€ μžˆλŠ” κ²½μš°μ—” κ°œν–‰μ„ ν•œλ‹€. 단, 첫번째 ν˜ΈμΆœλ˜λŠ” μ½”λ“œμ— λŒ€ν•΄μ„œλŠ” μ˜ˆμ™Έλ₯Ό λ‘”λ‹€.

    // ex. 1
    someThing.singleFunc(with: parameter)
        .secondFunc(with: someValue)
        .End(to: endValue)
    
    // ex. 2
    someThing.map {
        $0 * 2
    }
    .reduce(0) { result, intValue in 
        result + intValue
    }
  • self, Self ν‚€μ›Œλ“œμ—λŠ” κ°œν–‰μ„ ν•˜μ§€ μ•Šκ³ , μž‘μ„±ν•©λ‹ˆλ‹€.

    self.myProperty.setting()
    Self.self

μ΅œλŒ€ 쀄 길이

  • ν•œ 쀄은 μ΅œλŒ€ 120자λ₯Ό λ„˜μ§€ μ•Šμ•„μ•Ό ν•©λ‹ˆλ‹€.

    • 단, if let, guard let ꡬ문은 μ΅œλŒ€ 70자둜 μ œν•œ

    Xcode의 Preferences β†’ Text Editing β†’ Display의 'Page guide at column' μ˜΅μ…˜μ„ ν™œμ„±ν™”ν•˜κ³  120자둜 μ„€μ •ν•˜λ©΄ νŽΈλ¦¬ν•©λ‹ˆλ‹€.

Import

λͺ¨λ“ˆ μž„ν¬νŠΈλŠ” μ•ŒνŒŒλ²³ 순으둜 μ •λ ¬ν•©λ‹ˆλ‹€.

λ‚΄μž₯ ν”„λ ˆμž„μ›Œν¬λ₯Ό λ¨Όμ € μž„ν¬νŠΈν•˜κ³ , 빈 μ€„λ‘œ κ΅¬λΆ„ν•˜μ—¬ μ„œλ“œνŒŒν‹° ν”„λ ˆμž„μ›Œν¬λ₯Ό μž„ν¬νŠΈν•©λ‹ˆλ‹€.

넀이밍

클래슀

  • 클래슀 μ΄λ¦„μ—λŠ” UpperCamelCaseλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
  • 클래슀 μ΄λ¦„μ—λŠ” 접두사λ₯Ό 뢙이지 μ•ŠμŠ΅λ‹ˆλ‹€.

ν•¨μˆ˜

  • ν•¨μˆ˜ μ΄λ¦„μ—λŠ” lowerCamelCaseλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

  • ν•¨μˆ˜ 이름 μ•žμ—λŠ” λ˜λ„λ‘μ΄λ©΄Β get을 뢙이지 μ•ŠμŠ΅λ‹ˆλ‹€.

    • 쒋은 예:

      func name(for user: User) -> String?
    • λ‚˜μœ 예:

      func getName(for user: User) -> String?
  • Action ν•¨μˆ˜μ˜ 넀이밍은 'μ£Όμ–΄ + 동사 + λͺ©μ μ–΄' ν˜•νƒœλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

    • Tap(λˆŒλ €λ‹€ λ—Œ)*은 UIControlEvents의 .touchUpInside에 λŒ€μ‘ν•˜κ³ , *Press(λˆ„λ¦„)*λŠ”Β .touchDown에 λŒ€μ‘ν•©λ‹ˆλ‹€.
    • will~은 νŠΉμ • ν–‰μœ„κ°€ μΌμ–΄λ‚˜κΈ° 직전이고,Β did~λŠ” νŠΉμ • ν–‰μœ„κ°€ μΌμ–΄λ‚œ μ§ν›„μž…λ‹ˆλ‹€.
    • should~λŠ” 일반적으둜 Bool을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ— μ‚¬μš©λ©λ‹ˆλ‹€.

    쒋은 예:

    func backButtonDidTap() {
      // ...
    }

    λ‚˜μœ 예:

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

λ³€μˆ˜

  • λ³€μˆ˜ μ΄λ¦„μ—λŠ” lowerCamelCaseλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

μƒμˆ˜

  • μƒμˆ˜ μ΄λ¦„μ—λŠ” lowerCamelCaseλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

    쒋은 예:

    let maximumNumberOfLines = 3

    λ‚˜μœ 예:

    let MaximumNumberOfLines = 3
    let MAX_LINES = 3

μ—΄κ±°ν˜•

  • enum의 각 caseμ—λŠ” lowerCamelCaseλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

    쒋은 예:

    enum Result {
      case .success
      case .failure
    }

    λ‚˜μœ 예:

    enum Result {
      case .Success
      case .Failure
    }

μ•½μ–΄

  • μ•½μ–΄λ‘œ μ‹œμž‘ν•˜λŠ” 경우 μ†Œλ¬Έμžλ‘œ ν‘œκΈ°ν•˜κ³ , κ·Έ μ™Έμ˜ κ²½μš°μ—λŠ” 항상 λŒ€λ¬Έμžλ‘œ ν‘œκΈ°ν•©λ‹ˆλ‹€.

    쒋은 예:

      let userID: Int?
      let html: String?
      let websiteURL: URL?
      let urlString: String?

    λ‚˜μœ 예:

      let userId: Int?
      let HTML: String?
      let websiteUrl: NSURL?
      let URLString: String?

κ°œλ…μ  넀이밍

  • View, ViewModel에 ν•΄λ‹Ήν•˜λŠ” κ°œλ…μ€ 끝에 View, ViewModel을 뢙인닀.

    ex)
    class SoundViewModel
    class SettingView
  • Model에 ν•΄λ‹Ήν•˜λŠ” κ°œλ…μ€ Model을 뢙이지 μ•Šκ³ , κ°œλ… κ·ΈλŒ€λ‘œλ₯Ό μ΄λ¦„μœΌλ‘œ μ‚¬μš©ν•œλ‹€.

    ex)
    struct Sound
    struct PlayList
  • Singleton κ°μ²΄λŠ” Manager, Controller, Service 쀑 ν•˜λ‚˜λ₯Ό 뢙인닀.

    ex)
    enum NetworkManager
    struct AppController
    struct BackgroundSoundController
    class NotificationService

ν΄λž˜μŠ€μ™€ ꡬ쑰체

  • ν΄λž˜μŠ€μ™€ ꡬ쑰체 λ‚΄λΆ€μ—μ„œλŠ”Β selfλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • λ‚΄μž₯ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μ‘΄μž¬ν•œλ‹€λ©΄, λΆˆν•„μš”ν•œ μ΄ˆκΈ°ν™” ν•¨μˆ˜λ₯Ό μž¬κ΅¬μ„± ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
let frame = CGRect(x: 0, y: 0, width: 100, height: 100)

νƒ€μž…

  • Array<T>와 Dictionary<T: U>Β λ³΄λ‹€λŠ”Β [T],Β [T: U]λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

    // 쒋은 예:
    var messages: [String]?
    var names: [Int: String]?
    
    // λ‚˜μœ 예:
    var messages: Array<String>?
    var names: Dictionary<Int, String>?
  • Int, Float, String, Bool νƒ€μž…μ€ λ³€μˆ˜/μƒμˆ˜ μ„ μ–Έ μ‹œ, λͺ…μ‹œν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

    var isShowAnyView = false
    var referenceCount = 0

ν΄λ‘œμ €

  • νŒŒλΌλ―Έν„°μ™€ 리턴 νƒ€μž…μ΄ μ—†λŠ” Closure μ •μ˜μ‹œμ—λŠ”Β () -> Voidλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

    let completionBlock: (() -> Void)?
  • Closure μ •μ˜μ‹œ κ°œν–‰ν•˜μ—¬ μ½”λ“œ λΈ”λŸ­μ„ μž‘μ„±ν•©λ‹ˆλ‹€.

    쒋은 예

    intArray.map {
        $0 * 2
    }

    λ‚˜μœμ˜ˆ

    intArray.map { $0 * 2 }
  • Closure 인자 μž‘μ„± μ‹œ, κ°€λŠ₯ν•œ 경우 νƒ€μž… μ •μ˜λ₯Ό μƒλž΅ν•©λ‹ˆλ‹€.

    intArray.map {
      $0 * 2
    }
    • 인자 라벨의 μ •μ˜λŠ” ν•„μˆ˜κ°€ μ•„λ‹Œ ꢌμž₯μ‚¬ν•­μ΄μ§€λ§Œ, Closure λ‚΄μ˜ μ½”λ“œλΈ”λŸ­μ΄ 2쀄 이상인 경우 λ°˜λ“œμ‹œ 라벨을 μ‚¬μš©ν•©λ‹ˆλ‹€.

      intArray.map { intValue in
          let isOdd = (intValue % 2 == 1)
          return isOdd
      }
  • Closure μ •μ˜μ‹œ νŒŒλΌλ―Έν„°μ—λŠ” κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

    { operation, responseObject in
      // doSomething()
    }
  • Closure ν˜ΈμΆœμ‹œ 또 λ‹€λ₯Έ μœ μΌν•œ Closureλ₯Ό λ§ˆμ§€λ§‰ νŒŒλΌλ―Έν„°λ‘œ λ°›λŠ” 경우(ν›„ν–‰ ν΄λ‘œμ €), νŒŒλΌλ―Έν„° 이름을 μƒλž΅ν•©λ‹ˆλ‹€.

    쒋은 예:

    UIView.animate(withDuration: 0.5) {
      // doSomething()
    }

    단, νŒŒλΌλ―Έν„°μ— ν›„ν–‰ ν΄λ‘œμ €κ°€ 2개 이상 μ‘΄μž¬ν•˜λŠ” κ²½μš°μ—λŠ” μ•„λž˜ 두 κ°€μ§€ 쑰건을 μ€€μˆ˜ν•©λ‹ˆλ‹€.

    • λͺ¨λ“  ν΄λ‘œμ €λŠ” μΆ•μ•½ ν‘œν˜„μ„ μ‚¬μš©ν•©λ‹ˆλ‹€.
    • λ‘λ²ˆμ§Έ ν΄λ‘œμ €λΆ€ν„°λŠ” μ•žμ— μžˆλŠ” ν΄λ‘œμ €μ˜ 끝} μ—μ„œ μ€„λ°”κΏˆμ„ ν•˜μ§€ μ•Šκ³  라벨을 ν‘œμ‹œν•©λ‹ˆλ‹€.
    // UIView.animate(withDuration: TimeInterval, animations: () -> Void, completion: ((Bool) -> Void)?)
    UIView.animate(withDuration: 0.25) {
        // doSomething() about animations
      } completion: { finished in
        // doSomething() 
      }
    
    // SwiftUI Button
    Button {
    
    } label: {
    
    }

ν”„λ‘œκ·Έλž˜λ° ꢌμž₯사항

  • μƒμˆ˜λ₯Ό μ •μ˜ν•  λ•Œμ—λŠ”Β enumλ₯Ό λ§Œλ“€μ–΄ λΉ„μŠ·ν•œ μƒμˆ˜λΌλ¦¬ λͺ¨μ•„λ‘‘λ‹ˆλ‹€. μž¬μ‚¬μš©μ„±κ³Ό μœ μ§€λ³΄μˆ˜ μΈ‘λ©΄μ—μ„œ 큰 ν–₯상을 κ°€μ Έμ˜΅λ‹ˆλ‹€.Β structΒ λŒ€μ‹ Β enum을 μ‚¬μš©ν•˜λŠ” μ΄μœ λŠ”, μƒμ„±μžκ°€ μ œκ³΅λ˜μ§€ μ•ŠλŠ” μžλ£Œν˜•μ„ μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œμž…λ‹ˆλ‹€.

  • 더이상 상속이 λ°œμƒν•˜μ§€ μ•ŠλŠ” ν΄λž˜μŠ€λŠ” 항상 finalΒ ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•©λ‹ˆλ‹€.

  • ν”„λ‘œν† μ½œμ„ μ μš©ν•  λ•Œμ—λŠ” extension을 λ§Œλ“€μ–΄μ„œ κ΄€λ ¨λœ λ©”μ„œλ“œλ₯Ό λͺ¨μ•„λ‘‘λ‹ˆλ‹€.

    쒋은 예

    final class MyViewController: UIViewController {
      // ...
    }
    
    // MARK: UITableViewDataSource
    
    extension MyViewController: UITableViewDataSource {
      // ...
    }
    
    // MARK: UITableViewDelegate
    
    extension MyViewController: UITableViewDelegate {
      // ...
    }

    λ‚˜μœ 예

    final class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
      // ...
    }

Reference

[GitHub - StyleShare/swift-style-guide: StyleShareμ—μ„œ μž‘μ„±ν•œ Swift ν•œκ΅­μ–΄ μŠ€νƒ€μΌ κ°€μ΄λ“œ]

[GitHub - DeveloperAcademy-POSTECH/swift-style-guide: μ•„μΉ΄λ°λ―Έμ—μ„œ μ‚¬μš© ν•˜λŠ” μ½”λ”© μŠ€νƒ€μΌ κ°€μ΄λ“œ μž…λ‹ˆλ‹€.]

Clone this wiki locally