Skip to content

Ground Rules iOS

woongs edited this page Dec 1, 2020 · 13 revisions

iOS Ground Rules

  • ํŠน๋ณ„ํ•œ ์ผ์ด ์—†์œผ๋ฉด ์˜คํ”„๋ผ์ธ์œผ๋กœ ๋งŒ๋‚˜์„œ ๊ฐœ๋ฐœ ์ง„ํ–‰ (feat. ์Šคํ€˜์–ด์› ํ• ๋ฆฌ์Šค)
  • PR์˜ merge๋Š” ์ƒ๋Œ€๋ฐฉ์ด ์ฝ”๋“œ๋ฆฌ๋ทฐ ํ›„ ์ˆ˜ํ–‰ํ•œ๋‹ค (ํ•œ๋งˆ๋””๋ผ๋„ ์ •์„ฑ์Šค๋Ÿฝ๊ฒŒ ์ฝ”๋ฉ˜ํŠธ ๋‚จ๊ธฐ๊ธฐ)
  • Trouble Shooting์„ ์ž‘์„ฑํ•œ๋‹ค
    • ์ด์Šˆ๊ฐ€ ์ƒ๊ธฐ๋ฉด ๋ฌธ์ œ ์ƒํ™ฉ์„ ๋จผ์ € ๊ธฐ๋กํ•œ๋‹ค
    • ํ•ด๊ฒฐ ๊ณผ์ •์„ ์ตœ๋Œ€ํ•œ ์ž์„ธํžˆ ๊ธฐ๋กํ•˜๊ณ  ๊ฒฐ๋ก ์„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ ๋Š”๋‹ค
    • ๊ฐ€๋Šฅํ•˜๋ฉด ์Šคํฌ๋ฆฐ์ƒท์ด๋‚˜ ์ฝ”๋“œ๋ฅผ ์งง๊ฒŒ ๊ธฐ๋กํ•œ๋‹ค
    • ๊ณต๋™ Notion(ํ”ผ๋“œ๋ฐฑ์€ โ™ฅ๏ธ์ž…๋‹ˆ๋‹ค ๐Ÿ™Œ)์— ๊ธฐ๋กํ•˜๊ณ  ์ดํ›„ ์œ„ํ‚ค์— ์ถ”๊ฐ€ํ•œ๋‹ค
  • ํ•จ๊ป˜ ๋…ผ์˜ํ•œ // MARK ๋“ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ๋†’์ธ๋‹ค
  • Naming์ด๋‚˜ Convention๊ทœ์น™์€ swift api design guideline์„ ๋”ฐ๋ฅธ๋‹ค.
  • ํ• ๊ณ ๋ž˜DO๋Š” Human Interface Guidelines๋ฅผ ์ค€์ˆ˜ํ•œ๋‹ค

Coding Convention Rule

์•„๋ž˜์— ๋”ฐ๋กœ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ๋‚ด์šฉ์€ Google Swift Style Guide์„ ์ค€์ˆ˜ํ•œ๋‹ค.

method

  • return ์•ž์— ํ•œ ์ค„์€ ๋ˆ๋‹ค.
    • ๋‹จ, return ํ•œ ์ค„๋งŒ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋Š” ์˜ˆ์™ธ๋กœ ํ•œ๋‹ค.
  • ์ค‘๊ฐ„์— ๊ณต๋ฐฑ์€ ์˜๋ฏธ์žˆ๋Š” ๋‹จ์œ„๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.
func filterCompletedIfNeeded(for displayedTasks: [TaskListModels.DisplayedTask]) -> [TaskListModels.DisplayedTask] {
    guard displayCompleted else {
        return displayedTasks.filter { !$0.isCompleted }
    }
    
    return displayedTasks
}

private extension

  • private extension ๋‚ด๋ถ€์˜ ๋ฉ”์†Œ๋“œ์—๋Š” private ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค.

self

  • self ํ‚ค์›Œ๋“œ๋Š” ํ•„์š”์‹œ์—๋งŒ ๋ช…์‹œํ•œ๋‹ค.
    • self ์ฐธ์กฐ๊ฐ€ ํ•„์š”ํ•  ๋•Œ
    • ๋กœ์ปฌ ๋ณ€์ˆ˜์™€ ์ด๋ฆ„์ด ๊ฒน์น  ๋•Œ

guard let

  • ์กฐ๊ฑด๋ฌธ์ด ํ•˜๋‚˜์ด๊ณ  else ๋ฌธ์—์„œ ๊ฐ„๋‹จํ•œ return๋งŒ ํ•˜๋Š” ๊ฒฝ์šฐ
guard let value = value else { return 0 }
  • ์กฐ๊ฑด๋ฌธ์ด ํ•˜๋‚˜์ด๊ณ  else ๋ฌธ์ด ๊ธธ์–ด์ง€๋Š” ๊ฒฝ์šฐ
guard let first = values.first else {
  throw DiscombobulationError.arrayWasEmpty
}
  • ์กฐ๊ฑด๋ฌธ์ด ํ•˜๋‚˜์ง€๋งŒ ๊ธธ์–ด์งˆ ๊ฒฝ์šฐ ๋‚ด๋ ค์“ธ ์ˆ˜ ์žˆ๋‹ค.
guard let task = taskList.task(identifier: viewModel.id,
                               postion: viewModel.position,
                               parentPosition: viewModel.parentPosition)
else {
    return
}
  • ์กฐ๊ฑด๋ฌธ์ด 2๊ฐœ ์ด์ƒ์ธ ๊ฒฝ์šฐ
guard let value = aValueReturnedByAVeryLongOptionalThing(),
      let value2 = aDifferentValueReturnedByAVeryLongOptionalThing()
else { 
  doSomething() 
}

if else

  • ์กฐ๊ฑด๋ฌธ์ด ํ•œ ์ค„์ผ ๋•Œ,
if let index = index(of: thing, in: lotsOfThings) {
  // Found it.
} else {
  // Didn't find it.
}
  • ์กฐ๊ฑด๋ฌธ์ด ๋‘ ์ค„ ์ด์ƒ์ผ ๋•Œ,
if let index = index(of: thing, in: lotsOfThings),
   condition2 {
  // Found it.
} else {
  // Didn't find it.
}

๋ฐฐ์น˜ ์ˆœ์„œ

์ ‘๊ทผ์ œํ•œ์ž๋Š” ๋‹ค์Œ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฐ์น˜: private - private(set) - internal(์ƒ๋žต) - public

// MARK: - Constants

// MARK: - Properties

// MARK: Views

@IBOutlet weak private var addButton: UIButton!
private var label = UILabel()

// MARK: - View Life Cycle

// MARK: - Initialize

// MARK: - Methods

// MARK: Private

// MARK: IBActions

annotation

  • 8๊ธ€์ž ์ดํ•˜๋Š” ํ•œ ์ค„, ๊ทธ ์ด์ƒ์€ ๋‘ ์ค„๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
@objc func didTappedButton() {

}

@discardableResult
func remove(at index: Int) -> Int {

}

ํŠน์ • protocol์„ ์ฑ„ํƒํ•œ extension์—์„œ ๋ฉ”์†Œ๋“œ ๋ถ„๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ

  • ํ”„๋กœํ† ์ฝœ ๋ฉ”์†Œ๋“œ ํ•˜๋‹จ์— //MARK: - Helper Functions ๋กœ ๊ตฌ๋ถ„ํ•ด์„œ ๋ฐฐ์น˜ํ•œ๋‹ค.

protocol์„ ์ฑ„ํƒํ•˜์ง€ ์•Š์€ extension

  • ํŠน์ •ํ•œ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ๋“ค์ด 30์ค„ ์ด์ƒ์ด๋ฉด ๋ณ„๋„์˜ extension์œผ๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค. ๋‹จ, MARK๋ฅผ ํ†ตํ•ด ๊ธฐ๋Šฅ์„ ๋ช…์‹œํ•œ๋‹ค.
    • 30์ค„ ์ดํ•˜์ผ ๋•Œ ๋ถ„๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด, ํŒ€์›๊ณผ ์ƒ์˜ํ•˜์— ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํŠน์ • protocol์„ ์ฑ„ํƒํ•œ extension๋ณด๋‹ค ์œ„์— ๋ฐฐ์น˜ํ•œ๋‹ค.
Clone this wiki locally