Skip to content

Latest commit

ย 

History

History
347 lines (242 loc) ยท 7.6 KB

CodingConvention.md

File metadata and controls

347 lines (242 loc) ยท 7.6 KB

โŒจ๏ธ Coding Convention

์ฝ”๋“œ ๋ ˆ์ด์•„์›ƒ

๋“ค์—ฌ์“ฐ๊ธฐ ๋ฐ ๋„์–ด์“ฐ๊ธฐ

  • ๋“ค์—ฌ์“ฐ๊ธฐ์—๋Š” ํƒญ(tab) ๋Œ€์‹  2๊ฐœ์˜ space๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์ฝœ๋ก (:)์„ ์“ธ ๋•Œ์—๋Š” ์ฝœ๋ก ์˜ ์˜ค๋ฅธ์ชฝ์—๋งŒ ๊ณต๋ฐฑ์„ ๋‘ก๋‹ˆ๋‹ค.

    let names: String?
    var day: Date?

์ค„๋ฐ”๊ฟˆ

  • ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ตœ๋Œ€ ๊ธธ์ด๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„์„ ๊ธฐ์ค€์œผ๋กœ ์ค„๋ฐ”๊ฟˆํ•ฉ๋‹ˆ๋‹ค.

    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 ๊ตฌ๋ฌธ ์œ„์™€ ์•„๋ž˜์—๋Š” ๊ณต๋ฐฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

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

์ž„ํฌํŠธ

๋ชจ๋“ˆ ์ž„ํฌํŠธ๋Š” ์•ŒํŒŒ๋ฒณ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค. ๋‚ด์žฅ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋จผ์ € ์ž„ํฌํŠธํ•˜๊ณ , ๋นˆ ์ค„๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์„œ๋“œํŒŒํ‹ฐ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ž„ํฌํŠธํ•ฉ๋‹ˆ๋‹ค.

import UIKit

import SwiftyColor
import SwiftyImage
import Then
import URLNavigator

๋„ค์ด๋ฐ

ํด๋ž˜์Šค

  • ํด๋ž˜์Šค ์ด๋ฆ„์—๋Š” UpperCamelCase๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    CamelCase์—์„œ, ๋งจ ์•ž๊ธ€์ž๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ํ‘œ๊ธฐํ•˜๋Š” ๊ฒƒ์„ ๋œปํ•ฉ๋‹ˆ๋‹ค. PascalCase๋ผ๊ณ ๋„ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค.

    ๋‚˜๋จธ์ง€ ๋’ค์— ๋”ฐ๋ผ๋ถ™๋Š” ๋‹จ์–ด๋“ค์˜ ์•ž๊ธ€์ž๋Š” ๋ชจ๋‘ ๋Œ€๋ฌธ์ž๋กœ ํ‘œ๊ธฐํ•ฉ๋‹ˆ๋‹ค

  • ํด๋ž˜์Šค ์ด๋ฆ„์—๋Š” ์ ‘๋‘์‚ฌ๋ฅผ ๋ถ™์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•จ์ˆ˜

  • ํ•จ์ˆ˜ ์ด๋ฆ„์—๋Š” lowerCamelCase๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ํ•จ์ˆ˜ ์ด๋ฆ„ ์•ž์—๋Š” ๋˜๋„๋ก์ด๋ฉด get์„ ๋ถ™์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    ์ข‹์€ ์˜ˆ:

    func name(for user: User) -> String?

    ๋‚˜์œ ์˜ˆ:

    func getName(for user: User) -> String?
  • Action ํ•จ์ˆ˜์˜ ๋„ค์ด๋ฐ์€ โ€˜์ฃผ์–ด + ๋™์‚ฌ + ๋ชฉ์ ์–ดโ€™ ํ˜•ํƒœ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    • will์€ ํŠน์ • ํ–‰์œ„๊ฐ€ ์ผ์–ด๋‚˜๊ธฐ ์ง์ „์ด๊ณ , did๋Š” ํŠน์ • ํ–‰์œ„๊ฐ€ ์ผ์–ด๋‚œ ์งํ›„์ž…๋‹ˆ๋‹ค.
    • should~๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ Bool์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

    ์ข‹์€ ์˜ˆ:

    func backButtonDidTap() { // back ๋ฒ„ํŠผ์„ ํด๋ฆญ ํ–ˆ์„ ๋•Œ
      // ...
    }

๋ณ€์ˆ˜

  • ๋ณ€์ˆ˜ ์ด๋ฆ„์—๋Š” lowerCamelCase๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ƒ์ˆ˜

  • ์ƒ์ˆ˜ ์ด๋ฆ„์—๋Š” lowerCamelCase๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    ์ข‹์€ ์˜ˆ:

    let maximumNumberOfLines = 3

    ๋‚˜์œ ์˜ˆ:

    let kMaximumNumberOfLines = 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?
      

Delegate

  • Delegate ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœํ† ์ฝœ๋ช…์œผ๋กœ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

    ์ข‹์€ ์˜ˆ:

    protocol UserCellDelegate {
      func userCellDidSetProfileImage(_ cell: UserCell)
      func userCell(_ cell: UserCell, didTapFollowButtonWith user: User)
    }

    ๋‚˜์œ ์˜ˆ:

    protocol UserCellDelegate {
      func didSetProfileImage()
      func followPressed(user: User)
    
      // `UserCell`์ด๋ผ๋Š” ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒ
      func UserCell(_ cell: UserCell, didTapFollowButtonWith user: User)
    }

ํด๋ž˜์Šค์™€ ๊ตฌ์กฐ์ฒด

  • ํด๋ž˜์Šค์™€ ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์—์„œ๋Š” self๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ์—๋Š” Swift ๊ตฌ์กฐ์ฒด ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    ์ข‹์€ ์˜ˆ:

    let frame = CGRect(x: 0, y: 0, width: 100, height: 100)

    ๋‚˜์œ ์˜ˆ:

    let frame = CGRectMake(0, 0, 100, 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>?

์ฃผ์„

  • ///๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฌธ์„œํ™”์— ์‚ฌ์šฉ๋˜๋Š” ์ฃผ์„์„ ๋‚จ๊น๋‹ˆ๋‹ค.

    /// ์‚ฌ์šฉ์ž ํ”„๋กœํ•„์„ ๊ทธ๋ ค์ฃผ๋Š” ๋ทฐ
    class ProfileView: UIView {
    
      /// ์‚ฌ์šฉ์ž ๋‹‰๋„ค์ž„์„ ๊ทธ๋ ค์ฃผ๋Š” ๋ผ๋ฒจ
      var nameLabel: UILabel!
    }
  • // MARK:๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—ฐ๊ด€๋œ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ถ„์ง“์Šต๋‹ˆ๋‹ค.

    Objective-C์—์„œ ์ œ๊ณตํ•˜๋Š” #pragma mark์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์œผ๋กœ, ์—ฐ๊ด€๋œ ์ฝ”๋“œ์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    // MARK: Init
    
    override init(frame: CGRect) {
      // doSomething()
    }
    
    deinit {
      // doSomething()
    }
    
    // MARK: Layout
    
    override func layoutSubviews() {
      // doSomething()
    }
    
    // MARK: Actions
    
    override func menuButtonDidTap() {
      // doSomething()
    }

์ฝ”๋“œ ์œ„์น˜

class HomeVC: UIViewController { 
	// Mark: Variable Part
	// ๋ณ€์ˆ˜ ์ƒ์ˆ˜๋“ค์„ ์„ ์–ธํ•˜๊ธฐ
	// lowerCamelCase๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค
	// ex) var userName: String?
	
	// Mark: IBOutlet
	// Label,ImageView,Button ๋“ฑ @IBOutlet ์„ ์–ธํ•˜๊ธฐ
	// @IBOutlet weak var titleLabel: UILabel!

	// Mark: IBAction
	// ๋™์ž‘์„ ์„ ์–ธํ•˜๋Š” @IBAction ์„ ์–ธํ•˜๊ธฐ
	// ์ฃผ์–ด + ๋™์‚ฌ + ๋ชฉ์ ์–ด์˜ ํ˜•ํƒœ ์‚ฌ์šฉํ•˜๊ธฐ
	// ex) @IBAction func backButtonDidTap(_ sender: Any)
	
	// Mark: Life Cycle Part
	// ex) viewWillAppear(), ViewDidLoad()
}

extension HomeVC {
	// Mark: Function
	// ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ํ•จ์ˆ˜ ๋ถ€๋ถ„
	// ex)func name(for user: User) -> String?

}

// Mark: Extension
// ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•  ๋•Œ ์‚ฌ์šฉ
// ex) UITableViewDelegate

๋ผ์ด์„ผ์Šค

๋ณธ ๋ฌธ์„œ๋Š” Swift Style Guide๋ฅผ ์ฐธ๊ณ ํ•ด team meaning์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํฌ๋ฆฌ์—์ดํ‹ฐ๋ธŒ ์ปค๋จผ์ฆˆ ์ €์ž‘์žํ‘œ์‹œ 4.0 ๊ตญ์ œ ๋ผ์ด์„ผ์Šค์— ๋”ฐ๋ผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ €์ž‘๊ถŒ์€ ์ „์ˆ˜์—ด๊ณผ StyleShare์—๊ฒŒ ์žˆ์Šต๋‹ˆ๋‹ค.