2021. 8. 17. 21:52ㆍSwift, iOS Foundation
개발자로서 협업을 하게 되면, 같은 팀원들끼리 필수로 정해야 하는 규칙들이 있다.
개발을 할 때 지켜야 하는 Coding Convention,
깃을 사용하는 방법인 Git branch 전략,
모두가 알아볼 수 있도록 기록하는 Commit Convention,
프로젝트 내 파일을 관리하는 Foldering Convention 등이 그것들이다. (이 외에도 추가적인 규칙을 정하는 건 팀원들끼리의 자유이다.)
그중 오늘은 첫 번째로 Coding Convention에 대해 다루어 볼까 한다.
이미 솝트에서 경험한 세 번의 프로젝트 (합동 세미나, 솝커톤, 앱잼)에서 자의로든 타의로든 어느 정도 익숙해졌다 생각하지만, 그래도 아직 모르는 부분이 존재하고 이 부분은 iOS 개발자라면 꼭 짚고 넘어가야 하는 부분이기 때문에 정리를 해보려 한다.
오늘 포스팅은 솝커톤의 든든한 현규 선배께서 공부할 때 참고하라고 알려주신 주소,
아래 깃허브 링크에 담겨있는 Style Share를 참고해 작성했다.
무조건적으로 이 규칙을 따를 필요가 있다는 것이 아니라, 아래 스타일 가이드에는 이런 식으로 컨벤션을 정하는구나. "아 우리도 이런 것들은 정해보고 협업을 해봐야겠다"라고 참고하는 수준으로 살펴보면 좋겠다.
1️⃣ 코드 레이아웃: 코드의 가독성을 높이기 위해 설정해 주는 규칙
들여쓰기 | ✔️ 들여쓰기는 탭(tab) 대신 2개의 space를 사용한다. | |
띄어쓰기 | ✔️ 콜론을 쓸 때는 콜론 오른쪽 부분만 띄어서 쓴다. | let names: [String: String] |
줄바꿈 | ✔️ 함수 정의/호출 코드가 최대 길이를 초과하는 경우에 파라미터 이름을 기준으로 줄바꿈한다. ✔️ 단, 파라미터에 클로저가 2개 이상 중첩될 경우에 무조건 줄을 바꿔서 사용한다. ✔️ if-let, guard-let 구문이 길 경우 줄바꿈하고 한 칸 들여쓴다. |
UIView.animate( withDuration: 0.25, animations: { // 줄 바꿔서 코드 작성 } ) |
최대 줄 길이 | ✔️ 한 줄은 최대 99자를 넘지 않아야 한다. | |
빈 줄 | ✔️ 빈 줄에는 공백이 포함되서는 안된다. ✔️ 모든 파일은 빈 줄로 끝나야 한다. ✔️ MARK 구문 위, 아래에는 공백을 준다. |
// MARK: - View Life Cycle override func viewDidLoad() { .. } |
임포트 | ✔️ 모듈의 임포트는 알파벳 순으로 정렬한다. ✔️ 단, 내장 프레임워크를 먼저 임포트하고, 외장 프레임워크는 빈 줄로 구분 후 임포트할 수 있도록 한다. |
import UIKit import SnapKit import Then |
2️⃣ 네이밍: 직관성을 위해 정하는 규칙
Swift 네이밍의 공통으로 적용되는 규칙은, Python에서 사용하는 snake_case 대신 CamelCase를 사용해서 네이밍을 한다는 것이다.
또한, 이름만 보았을 때에도 직관적으로 어떤 역할을 하는 인스턴스, 메서드인지 알아들을 수 있도록 하는 것이 핵심이다.
- lowerCamelCase: 함수, 메소드, 변수, 상수 등에 사용
- UpperCamelCase: 클래스, 구조체, 열거형, Extension 등에 사용
클래스와 구조체 | ✔️ UpperCamelCase를 사용하며, 클래스 이름은 접두사를 붙이지 않는다. | class SomeClass { ... } |
함수 | ✔️ LowerCamelCase를 사용한다. ✔️ 함수 이름 앞에는 되도록 get을 붙이지 않도록 한다. ✔️ Action 함수의 네이밍은 "주어 + 동사 + 목적어" 형태를 사용한다. 1) Tab은 .touchUpInside에 대응, Press는 .touchDown Events에 대응한다. 2) will~은 특정 행위가 일어나기 "직전"을 의미 3) did~는 특정 행위가 일어난 "직후"를 의미 4) should~는 대개 Bool을 반환하는 함수에 사용 |
func backButtonDidTap() { ... } |
변수/상수 | ✔️ LowerCamelCase를 사용한다. | var someVar = 0 let someVar = 0 |
열거형 | ✔️ enum의 이름은 UpperCamelCase를 사용한다. ✔️ enum의 각 case는 lowerCamelCase를 사용한다. |
enum Result { case .success case .failure } |
프로토콜 | ✔️ UpperCamelCase를 사용한다. ✔️ 프로토콜을 채택할 때는 콜론과 빈칸을 넣어 구분한다. (띄어쓰기 규칙 동일) |
extension VC: SomeProtocol { ... } |
약어 | ✔️ 약어로 시작하는 경우에 소문자로 표기하고, 그 외에 경우에는 항상 대문자로 표기한다. | let userID: Int var urlString: String |
3️⃣ 클로저
✔️ 파라미터와 리턴 타입이 없는 클로저는 () -> Void를 사용한다. | let someClosure: (() -> Void)? |
✔️ 클로저 정의 시 파라미터에는 괄호를 사용하지 않는다. | { make in ... } (O) { (make) in ... } (X) |
✔️ 클로저 정의 시 가능한 경우 타입 정의를 생략한다. | completion: { (make: Bool) -> Void in .. } // 이렇게 사용하지 말라는 뜻! |
✔️ 클로저 호출 시 또다른 유일한 클로저를 마지막 파라미터로 받는 경우, 파라미터 이름을 생략한다. | 후행 클로저 적용하라는 뜻! |
4️⃣ 클래스와 구조체
✔️ 클래스와 구조체 내부에는 self를 명시적으로 사용한다. | |
✔️ 구조체를 생성할 때는 Swift 구조체 생성자를 사용한다. | let frame = CGRect(x: ..., y: ...) |
5️⃣ 타입
Array | ✔️ Array 타입은 Array<T>보다 [T]를 사용하도록 한다. | let names: [String] |
Dictionary | ✔️ Dictionary 타입은 Dictionary<T: U>보다 [T: U]를 사용하도록 한다. | let names: [Int: String] |
6️⃣ 주석: 내 코드를 다른 협업하는 개발자들에게도 잘 설명할 수 있는 방법!
✔️ 주석 표시 이후에는 한 칸 띄어쓰기 후, 내용을 작성한다. | |
✔️ // MARK: - 를 사용하여 연관된 코드와 연관되지 않은 코드를 구분하도록 한다. | // MARK: - View Life Cycle |
✔️ /// 를 사용해서 퀵헬프 주석을 남긴다. |
7️⃣ 프로그래밍시 추가 권장사항: 권장사항이긴 하지만 어지간하면 지키는 것이 좋다!
변수 초기화 | ✔️ 변수를 정의할 때 함께 초기화하도록 한다. | let label = UILabel.then { $0.textColor = ... } |
enum 활용 | ✔️ 상수를 정의할 때, struct 대신 enum을 사용해서 모아둔다. ✔️ 재사용성과 유지보수 측면, 그리고 생성자가 제공되지 않는 자료형을 사용하기 위해서이다. |
private enum Color { static let mainColor = ... } |
final 키워드 | ✔️ 더 이상 상속이 발생하지 않는 클래스는 항상 final 키워드로 선언한다. | final class ViewController { ... } |
프로토콜 extension | ✔️ 프로토콜을 적용했을 때 관련 메서드는 extension으로 모아둔다. | extension VC: UITableViewDelegate { ... } |
생명주기 | ✔️ 생명 주기에는 최대한 코드를 간결하게 작성한다. |
'Swift, iOS Foundation' 카테고리의 다른 글
[Foundation] UserDefaults를 사용해서 데이터를 전달하는 방법 (0) | 2021.12.17 |
---|---|
[Swift] 함수 앞에 private가 붙어 있던 이유, 접근 제어(Access Control) (0) | 2021.11.08 |
[Swift] 타입캐스팅(Type Casting) 완전 정복하기: is? as as? as! 키워드 내용 정리 (0) | 2021.11.06 |
[Swift] 옵셔널(Optional) 완전 정복하기: 개념부터 옵셔널 바인딩까지 (0) | 2021.08.24 |
[Swift] Closure 완전 정복하기: 일급 객체부터 작성법, 그리고 @escaping까지 (0) | 2021.08.12 |